Interfaces In C# 8.0

As we all know C# 8.0 was released a few days back which has come up with the many exciting features along with this release of C# there are significant amount of changes in interfaces have also been happened so with this article let’s try to explore the new feature and try to learn how we can use them in the projects. Agenda for this article will be like below

  1. Interface today
  2. Default Methods
  3. Diamond Problem
  4. Modifiers in Interfaces
  5. Conclusion

Interfaces Today

As a developer we all make use of the interface be it to create the loosely coupled component or to define the contract which should be implemented by the concrete class. Today’s interfaces never come up with the body, no modifiers it is the responsibility of the implementer class to provide body and assign some modifiers to it, if the class does not implement the method compiler catches it and gives the error saying we need to implement the interface.

Throughout this application, we will use the example of the Logger class and do the changes accordingly

using System;
public interface ILogger
{
void Log(string Info);
}
public class TextLogger : ILogger
{
public void Log(string Info)=> Console.Write("In base Logger");
}
view raw interface8 hosted with ❤ by GitHub

We have defined one interfaces Called ILogger with one method Log () we have a class Called TextLogger which is implementing the interface ILogger. This is perfectly fine considering the current state of the design. Now the problem occurs when we want to extend the ILogger and need to add some more information in it like below

public interface ILogger
{
void Log(string info);
void Log(string type of information,string info)
}
view raw iLogger hosted with ❤ by GitHub

Now we will have an issue here as this new method must be implemented by the class where this interface is used and the compiler will show us an error until this is done like below

1

Now considering this interfaces is been used by multiple classes, this will break many changes and it will be really painful to make these changes across the implementation depending on the places where this interface is used we need to implement this method across to make our code compile.

To overcome this, C# 8 come up with the idea of the Default Methods in interfaces

Default Interface Methods

Main Reason to get this feature in C# 8.0 is to provide the default implementation for the interface methods so how we can do this let’s see the following example:

using System;
public interface ILogger
{
void Log(string info);
//Default implementation
void LogInfo(string type of information,string info)=>Console.Write(typeofInformation+ " " + info);
}
public class TextLogger : ILogger
{
public void Log(string info)=> Console.Write("In base Logger");
}

Here we can see the in the interface itself we have provided the implementation for the function, here our Class TextLogger does not need to implement this method and there will not be any compile-time error

Now to use this interface in our application lets change our main method and let us see how we can use it:

class Program
{
static void Main(string[] args)
{
ILogger _logger = new TextLogger();
_logger.LogInfo("Test","test"); // It will call the Default method of the interface.
} }}
view raw programClass hosted with ❤ by GitHub
2

One more thing that we need to check is Default methods will only work if the class is contextually treated as interfaces if we are not doing that then Default method implementation will not be available for the use

In the above screenshot, we can see if while creating the object from the class we can see the default method is not available to use.

If we look at this feature closely we can see that this can lead to the very well-known problem of the Multiple Inheritance which is famously called as Diamond Problem by design C# won’t face any issues as Multiple inheritances is not possible with the classes and interfaces didn’t have implementation of the methods but with the default method this is going be change let’s see how it will be handled in C#8.0

Diamond Problem

Diamond problem is one of the big issues in languages as C# classes does not support this feature which is a result of the multiple inheritances, but interfaces can introduce this problem up to some extent let’s see how C# handles them following diagram illustrates what diamond problem is

3

Above figure depicts the Diamond problem very well now let’s see with the default interfaces how this problem can arise and how c# handles it

Let’s design the interfaces like below:

Interface First
{
void WritetoConsole() => Console.Write("In First");
}
interface Second:First{
void First.WritetoConsole()=>Console.Write("In Second");
}
interface Third:First{
void First.WritetoConsole()=>Console.Write("In Third");
}
class FinalClass : Second,Third
{
}
view raw diamondProblem hosted with ❤ by GitHub
4

Error message will be:

Interface member ‘First.WritetoConsole()’ does not have a most specific implementation. Neither ‘Second.First.WritetoConsole()’, nor ‘Third.First.WritetoConsole()’ are most specific. (CS8705) [DeaultInterfaceDemo]

In order to solve this problem as depicted in the Error itself we need to provide the most specific override at the time at the time of execution Dotnet design team has told specifically about it as follows

“A class implementation of an interface member should always win over a default implementation in an interface, even if it is inherited from a base class. Default implementations are always a fall back only for when the class does not have any implementation of the member at all.”

Let’s see how we can provide the default implementation and solve this diamond problem:

using System;
interface First
{
void WritetoConsole() => Console.Write("In First");
}
interface Second:First{
void First.WritetoConsole()=>Console.Write("In Second");
}
interface Third:First{
void First.WritetoConsole()=>Console.Write("In Third");
}
class FinalClass : Second,Third
{
void First.WritetoConsole(){
Console.Write("From Final class");
}}

Modifiers in Interfaces

Traditionally till the arrival of the c# 8.0 we could not use the modifiers in the interfaces with the c# 8.0 we can use them, till now modifiers like private, protected, internal , public and virtual are allowed, By design all the default interfaces methods are made virtual unless we are making them private or sealed, All the members without body are treated as abstract by default making it compulsory to be implemented in the concrete classes.

using System;
interface IInterfaceModifiers
{
//By Default default method is private
virtual void DefaultMethod()=>Console.WriteLine("Default method");
//Private Default Method
private void privatedefaultmethod()=>Console.WriteLine(" private Default method");
//Protected Default Method
protected void ProtectedDefaultMethod()=>Console.WriteLine(" protected Default method");
// Public Default Method
public void PublicDefaultMethod()=>Console.WriteLine(" public Default method");
virtual void VirtualDefaultMethod()=>Console.WriteLine("Virtual Default method");
abstract void AbstractDefaultMethod();
}
class InterfaceModifierDemo : IInterfaceModifiers
{ public void AbstractDefaultMethod() => Console.WriteLine("Abstract virtual method");}
namespace DeaultInterfaceDemo
{
class Program
{
static void Main(string[] args)
{
IInterfaceModifiers i= new InterfaceModifierDemo();
i.AbstractDefaultMethod();
i.DefaultMethod();
i.PublicDefaultMethod();
i.VirtualDefaultMethod();
}
}
}
view raw modifiers hosted with ❤ by GitHub

When we run above code we can see the following output on the console:

Abstract virtual method

Default method

public Default method

Virtual Default method

Apart from this few observations that I come across in this example.

  • When we make a method virtual we can override that method in interface itself and we cannot override it in the implementation class.
  • When we make one method protected it is available in the inheriting interface rather than implementing class by default the members of the interfaces are abstract which makes it compulsory for the implementing class to implement them properly.

Summary

We have seen the most controversial yet most exciting feature of the C#8.0 it will change the way we have been using the interfaces in the design , which will certainly help developer in producing less breaking changes but also it will come up with its own challenge of performance and design perspectives , Another thing to add is this feature will not be available in the .net Framework for now but included in the .net core and Core CLR as well MONO.

References

https://www.infoq.com/articles/default-interface-methods-cs8/

C# 8: Default Interface Methods Implementation

https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-04-19.md

3 thoughts on “Interfaces In C# 8.0

Leave a comment