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
You cannot override a non-virtual or static method. The overridden base method must be
virtual
,abstract
, oroverride
.
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:
- Create a subclass
- Implement the interface that provides the method
- 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.