There is a very simple way to handle this:
- Declare the default method as static. Don't worry, you will still be able to override it in a class that inherits from it.
- Call the default method using the same type of syntax when calling a static method of a class, only substitute the interface name for the class name.
This code applies to C#8 or later, and it won't work if building against the .NET Framework. I ran it on Windows 10 with C#9, running on .NET 6, preview 5.
Example:
public interface IGreeter
{
private static int DisplayCount = 0;
public static void SayHello(string name)
{
DisplayCount++;
Console.WriteLine($"Hello {name}! This method has been called {DisplayCount} times.");
}
}
public class HappyGreeter : IGreeter
{
public void SayHello(string name)
{
// what can I put here to call the default method?
IGreeter.SayHello(name);
Console.WriteLine("I hope you're doing great!!");
}
}
public class CS8NewFeatures
{
// This class holds the code for the new C# 8 features.
//
public void RunTests()
{
TestGreeting();
}
private void TestGreeting()
{
// Tests if a default method may be called after a class has implemented it.
//
var hg = new HappyGreeter();
hg.SayHello("Pippy");
hg.SayHello("Bob");
hg.SayHello("Becky");
}
}
Example Output:
Hello Pippy! This method has been called 1 times.
I hope you're doing great!!
Hello Bob! This method has been called 2 times.
I hope you're doing great!!
Hello Becky! This method has been called 3 times.
I hope you're doing great!!
Static fields are also now allowed in interfaces as this example shows.
If you can't use a static interface method for some reason, then you can always rely on the following technique:
- Put the default method implementation code into a separate static method.
- Call this static method from the default implementation method.
- Call this static method at the top of the class implementation of the interface method.
Example:
public class DefaultMethods
{
// This class is used to show that a static method may be called by a default interface method.
//
public static void SayHello(string name) => Console.WriteLine($"Hello {name}!");
}
public interface IGreeter
{
void SayHello(string name) => DefaultMethods.SayHello(name);
}
public class HappyGreeter : IGreeter
{
public void SayHello(string name)
{
// what can I put here to call the default method?
DefaultMethods.SayHello(name);
Console.WriteLine("I hope you're doing great!!");
}
}
public class CS8NewFeatures
{
// This class holds the code for the new C# 8 features.
//
public void RunTests()
{
TestGreeting();
}
private void TestGreeting()
{
// Tests if a default method may be called after a class has implemented it.
//
var hg = new HappyGreeter();
hg.SayHello("Bob");
}
}
Sample Output:
Hello Bob!
I hope you're doing great!!
Can I have my concrete implementation call that default method?
I don't believe so, although there looks to be plans to add that throughbase
. learn.microsoft.com/en-us/dotnet/csharp/language-reference/… – Lindanebase.method()
– CondignIGreeter
a static method that implements functionality of the methodSayHello
. And then this method can be call from the classHappyGreeter
. Do you consider such approach? – Selsyn