Overriding non-virtual methods in C#

C# lets us add virtual modifier to a method to indicate that it can be overridden by the subclasses of that (non-sealed) class.

Problem

C# spec says:

You cannot override a non-virtual or static method. The overridden base method must be virtual, abstract, or override.

When working with a library, sometimes we really need to override a method to plug our own logic, but darn it, it's not virtual, definitely not abstract, it doesn't have override either. What do we do?

Trick

We have one crucial condition for this trick to work: the method we want to override must come from an interface implemented by the class.

Take this example:

interface IEmailSender {
    Task<SendResult> SendAsync(MailMessage email);
}

public class DefaultEmailSender : IEmailSender
{
    public Task<SendResult> SendAsync(MailMessage email)
    {
        // ...
    }
}

We want to override the SendAsync method, but it's not virtual/override. Don't fret, in three easy steps, we can override it:

  1. Create a subclass
  2. Implement the interface that provides the method
  3. Add new modifier
public class ConsoleEmailSender : DefaultEmailSender, IEmailSender
{
    public new Task<SendResult> SendAsync(MailMessage email)
    {
        // custom logic!
    }
}

We can modify the arguments, call the base implementation and modify the result:

public class ConsoleEmailSender : DefaultEmailSender, IEmailSender
{
    public new async Task<SendResult> SendAsync(MailMessage email)
    {
        // ... modify the arguments

        Console.WriteLine(email.Subject);
        email.Subject = "console";
        
        var result = await base.SendAsync(bindingContext);

        // ... modify the results

        return result;
    }
}

It is a neat little trick that I resort to from time to time.

Last updated: