1

I'm reading this blog of .NET Engineering Team and they have introduced a new feature of default implementation for Interface. I'm confused related to its motive other than multiple level inheritance problem of abstract class. Other than that I'm not able to figure out any other benefit. Consdier the following code:

C# 7 (Not possible to provide method definitions)

interface ILogger
{        
    void LogData(dynamic data, dynamic logMode);

    bool SendStatusEmail(string emailAddress);

}
public class EmployeeLog : ILogger
{
    public void LogData(dynamic data, dynamic logMode)
    {
        throw new NotImplementedException();
    }

    public bool SendStatusEmail(string emailAddress)
    {
        throw new NotImplementedException();
    }
}

public abstract class Logger
{
    public abstract void LogData(dynamic data, dynamic logMode);

    public bool SendStatusEmail(string emailAddress)
    {
        // Email Sending Code
        return true;
    }
}

public class EmployeeLog : Logger
{
    public override void LogData(dynamic data, dynamic logMode)
    {
        throw new NotImplementedException();
    }
}

C# 8 (Possible to provide method definitions)

interface ILogger
{
    void LogData(dynamic data, dynamic logMode);

    public bool SendStatusEmail(string emailAddress)
    {
        // Email Sending Code
        return true;
    }

}
public class EmployeeLog : ILogger
{
    public void LogData(dynamic data, dynamic logMode)
    {
        throw new NotImplementedException();
    }
}

public abstract class Logger
{
    public abstract void LogData(dynamic data, dynamic logMode);

    public bool SendStatusEmail(string emailAddress)
    {
        // Email Sending Code
        return true;
    }
}

public class EmployeeLog : Logger
{
    public override void LogData(dynamic data, dynamic logMode)
    {
        throw new NotImplementedException();
    }
}

In C# 8, both abstract class and interface can do the same work of providing default implementation to its members. I have following doubts related to it:

  • If Interface provides default implementation and also supports multiple inheritance, what is the need to abstract class in c# 8?

  • What will happen in case of this scenario?

:

interface ILogger
{
   public bool SendStatusEmail(string emailAddress)
{
    // Email Sending Code
    return true;
  }
}
interface IEmail
{
    public bool SendStatusEmail(string emailAddress)
    {
        // Email Sending Code
        return true;
    }

}

public class EmployeeLog : ILogger, IEmail
{
}

public class Test
{
    EmployeeLog emp = new EmployeeLog();
    emp.SendStatusEmail();  //Which function it will refer to?
}
Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
Sahil Sharma
  • 1,813
  • 1
  • 16
  • 37
  • 2
    Maybe this will answer your question, https://www.infoq.com/articles/default-interface-methods-cs8 – fhnaseer Jan 31 '19 at 08:26
  • Not really and this has been asked before. It's meant to implement traits, the way Java and PHP do, not multiple inheritance. The blog does explain the benefits, and they are significant. – Panagiotis Kanavos Jan 31 '19 at 10:31
  • 1
    I gone through the blog and it cleared a lot of doubts. However still wondering why abstract class is still relevant in C# 8? – Sahil Sharma Jan 31 '19 at 10:36
  • @iSahilSharma because abstract classes are still classes with state, instance members, private methods etc. An interface can't hold state even with default implementations. Think of the Stream class. It contains a *lot* of functionality that's common for all streams and definitely has state. It has quite a lot of private implementation code too, that shouldn't be visible either to consumers or derived classes – Panagiotis Kanavos Feb 07 '19 at 09:27
  • The only way to call the default implementation is by using the interface reference, you can't call it through the class object reference. In other words, the class does not inherit it. So there can't be any multiple inheritance. – Hans Passant Sep 09 '19 at 13:00
  • You say you are not able to figure out any benefit; I note that Java has had this feature for many years. Can you find examples of how this feature benefitted Java programmers? – Eric Lippert Sep 25 '19 at 06:09
  • IMHO, abstract classes are used to define a family. (they derived classes are related to each other somehow) but in the case of interfaces it is not. Even non related classes can implement the same interface, like a Stream class implementing IDispose for cleaning up and an EmailSender implementing the same interface. The Stream class and EmailSender is not related to each other. – Thangadurai Sep 25 '19 at 06:20

1 Answers1

0

Answer: Abstract classes can have fields and virtual methods

This is why multiple inheritance is not supported in C# (also in Java)

Fields with multiple inheritance may cause issues when:

class A : B, C {...}
class C : D {...}
class B : D {...}
class D
{
    ...
    protected int _value;
    ...
}

Should the inherited B and C share the same instance of _value?

There are reasons to both.

If so, the logics in B and C could interfere with each other because the value of _value is neither predictable for B nor for C.

And B and C do not even know that they would work with each other as parts of the same object.

If not, which instance of _value should be accessed from A?

Similar issues apply to virtual methods. Because the virtual table would be no longer linear when both B and C override a virtual method defined in D.

Solving these would make the inheritance relationship very complex, therefore Java does not support multiple inheritance and introduced the concept of interface, and this also came to C#.

How interface solved this problem

There are only method declarations (regarding properties as accessors as methods) in interface definitions, so there could not be fields and method overridings. So there are no multiple inheriting issues.

How C# 8.0 can allow interfaces to have method bodies without causing these issues

Default implementation in C# 8.0 does not use the same logic as the virtual table in class inheritance logics, but a priority mechanism that chooses the implementation from the nearest implemented interface to be the only available implementation, therefore there are no virtual table issues.

There are still no fields allowed in interfaces therefore there are no field issues.

How to choose between interface with default implementations and abstract classes

  • Syntactically, if the type must have fields or virtual/abstract methods with multiple overrides in use, from the types in the inheritance tree, use abstract class, otherwise interface.

  • Logically, if the main part of logic should be implemented in this type and some single details are to be specified within the derived/implementation class, use abstract class. If the type only specifies how it could be accessed and the implemented methods are simply making convenience for the implementation class, like converting an argument from an alternative type to the mainly implemented type, use interface with default implementations.

Alsein
  • 4,268
  • 1
  • 15
  • 35