Home > other >  Why does C# allows definitions of non-abstract, non-static methods inside of an interface?
Why does C# allows definitions of non-abstract, non-static methods inside of an interface?

Time:03-06

I was experimenting on this thing and I found that C# actually allows you to have non-static, non-abstract method definitions inside an interface, which made totally no sense to me as it is not according to the rules of Object Oriented paradigm. Here's the code you may test out in your systems which actually compiles and runs successfully the way you would expect it to.

Interface Test : -

public interface Test
{
    public void Display() {
        Console.WriteLine("Display called from interface");
    }
}

Class Derived that implements test: -

public class Derived : Test
{
    public void SomeTestMethod()
    {
        Console.WriteLine("Just a method");
    }
}

Program.cs : -

class Program
{
    static void Main(string[] args)
    {
        Test instance = new Derived();
        instance.Display();
    }
}

This code would run perfectly without any issues producing the output "Display called from interface" in the console. This makes absolutely no sense to me as to why is this even allowed. Won't this just re-introduce the diamond problem or the issue of having ambiguity in methods defined in two interfaces when both of them are implemented by a single class. I am not sure if this is something that has been introduced in newer versions of C# or is it a .Net Core thing. If anyone knows the reason please let me know. Thanks in advance.

CodePudding user response:

Answer to this question would be depends.

  1. This feature was not there and it was introduce in C# 8.0.
  2. It will be great help when you have to change interface in existing application or package that is consumed by many other third party. It provide back-word compatibility and also some how justify Interface Segregation of SOLID as it will not force to implement those method if it is not required.

Example.

  1. Consider Scenario. This is version one of Interface IService.
public interface IService
{
    string GetMessage(); 
}
  1. Publish the package or provide to other application.
  2. That application implement interface.
public class ServiceA : IService
{
    public string GetMessage()
    {
        return "From ServiceA";
    }
}

public class ServiceB : IService
{
    public string GetMessage()
    {
        return "From ServiceB";
    }
}

Now there is requirement to change in interface ( best case avoid this) but if you have to do it.

Before C# 8.0

public interface IService
{
    string GetMessage();
    string NewMessage(); 
}

Now as soon this interface publish and consumed by other already implemented that interface. It break. ( This is breaking change.)

from C# 8.0 you can provide default implementation.

public interface IService
{
    string GetMessage();
    string NewMessage()
    {
        return "From Interface";
    }
}

ServiceA decided to implement but ServiceB does not but it will not break previously running application.

public class ServiceA : IService
{
    public string GetMessage()
    {
        return "From ServiceA";
    }

    public string NewMessage()
    {
        return "From ServiceA NewMessage";
    }
}

public class ServiceB : IService
{
    public string GetMessage()
    {
        return "From ServiceB";
    }
}

CodePudding user response:

Since version 8.0, C# has support for default interface methods, which have some properties of traits, also it is similar to Java's "Default Methods"

this feature enables C# to interoperate with APIs targeting Android (Java) and iOS (Swift), which support similar features.

The Question now is what is the difference between Abstract class and interface if we can write implementation in the interface.

This new feature in C# 8 is used when you have already written code that use interface and there are multiple classes that inherit from this interface and you want to add additional functionality to the interface without breaking the existing classes that are using my interface, what you can do is use default interface methods and add that functionality, this allow you to update your code without interrupting people who use your interface

  • Related