Do C# 8 default interface implementations allow for multiple inheritance
Asked Answered
D

2

35

According to https://blogs.msdn.microsoft.com/dotnet/2018/11/12/building-c-8-0/, one of the new features coming in C# 8 is the default implementation of interfaces. Will this new feature also implicitly allow for multiple inheritance? If not, what exactly will happen if I try the following:

public interface A { int Foo() => 1; }
public interface B { int Foo() => 2; }
public class C : A, B { }
Disunion answered 13/11, 2018 at 10:10 Comment(11)
There is no reason to expect that it wouldn't work. Read the link again, focussing on The above code will produce the compile-time error: AnyClass does not contain a member DefaultMethod.. This seems to indicate that something akin to explicit interface implementation is used. Also see dotnetcoretutorials.com/2018/03/25/… .Flame
As I know, you can point parent explicit: A.Foo() and B.Foo().Gayle
You can implement more than 1 interfaceGuardian
@Guardian that's not the point. The question is: if two interfaces implement a method with the same signature, and a class implements both those interfaces, which method will win and why?Alow
@Alow A will win if the variable is of type A. B will win if the variable is of type B.Flame
@Flame that's in the case of explicit interface implementations. Question is, what if the variable is of type C, will you be able to call C.Foo(), and which implementation will that call, or will it fail to compile because C.Foo() doesn't exist, or because no best overload can be matched?Alow
Check the link I provided @Alow and the one provided by the OP . No, you can't call C.Foo as per my earlier comment. Now, your answer raises a great question (what if there is a third interface that 'inherits' the two of them?) - which is a great question, but a slightly different one.Flame
And now I realise my earlier link was the wrong one. infoq.com/articles/default-interface-methods-cs8 is the one I meant. My apologies.Flame
@Flame I think you do have a point, the specs say "Note that a class does not inherit members from its interfaces; that is not changed by this feature". It's as if the method implemented in the interface does not "live" in the class at all.Alow
@Alow That is what I meant by This seems to indicate that something akin to explicit interface implementation is used.Flame
@Flame good point, I'd love to, but given a spec nor an implementation is complete there's nowhere I can validate my suspicions. There's only sharplab.io/…, but I'm not sure how authoritative that is.Alow
F
15

Credit to @CodeCaster for his/her great comments that prompted this answer.

The proposal states:

Note that a class does not inherit members from its interfaces; that is not changed by this feature:

Thus, it seems reasonable (although impossible to confirm with 100% certainty until it is shipped) that:

public interface A { int Foo() => return 1; }
public interface B { int Foo() => return 2; }
public class C : A, B { }

will work fine.

Just as the proposal shows:

new C().M(); // error: class 'C' does not contain a member 'M'

then we can assume, your version:

new C().Foo();

will also not compile.

The proposal shows:

IA i = new C();
i.M();

as valid, which is equivalent to your:

A i = new C();
i.Foo();

Since i is declared as type A there is no reason to assume the same would not work if A was changed to B - there are no collisions to speak of.

The entire point of this feature is to allow interfaces to be extended in a safe way (see this video). If this only worked if you implemented one interface, that seems contrary to the objective of the feature. And given the feature appears to be implemented in a way roughly akin to explicit interface implementation (which is why we can't invoke C.Foo() directly), I think we can reasonably assume that it will most likely allow for multiple interface implementation.

Flame answered 13/11, 2018 at 12:53 Comment(0)
K
31

Your question is answered by Mads Torgersen in the blog post you linked to:

Actually interfaces are still quite far from abstract classes. Classes don’t inherit members from interfaces, so if a class leaves a member M implemented by the interface, the class does not have a member M! It’s like an explicit implementation today; you have to convert to the interface in order to get at such members.

So with your example:

public interface A { int Foo() => 1; }
public interface B { int Foo() => 2; }
public class C : A, B { }

You cannot do this:

var something = new C();
var x = something.Foo(); /* does not compile */

You can do the following:

var something = new C();
var x = ((A)something).Foo(); /* calls the implementation provided by A */
var y = ((B)something).Foo(); /* calls the implementation provided by B */
Kourtneykovac answered 14/11, 2018 at 9:58 Comment(0)
F
15

Credit to @CodeCaster for his/her great comments that prompted this answer.

The proposal states:

Note that a class does not inherit members from its interfaces; that is not changed by this feature:

Thus, it seems reasonable (although impossible to confirm with 100% certainty until it is shipped) that:

public interface A { int Foo() => return 1; }
public interface B { int Foo() => return 2; }
public class C : A, B { }

will work fine.

Just as the proposal shows:

new C().M(); // error: class 'C' does not contain a member 'M'

then we can assume, your version:

new C().Foo();

will also not compile.

The proposal shows:

IA i = new C();
i.M();

as valid, which is equivalent to your:

A i = new C();
i.Foo();

Since i is declared as type A there is no reason to assume the same would not work if A was changed to B - there are no collisions to speak of.

The entire point of this feature is to allow interfaces to be extended in a safe way (see this video). If this only worked if you implemented one interface, that seems contrary to the objective of the feature. And given the feature appears to be implemented in a way roughly akin to explicit interface implementation (which is why we can't invoke C.Foo() directly), I think we can reasonably assume that it will most likely allow for multiple interface implementation.

Flame answered 13/11, 2018 at 12:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.