根据https://blogs.msdn.microsoft.com/dotnet/2018/11/12/building-c-8-0/,C# 8 中的新功能之一是接口的默认实现。这个新特性是否也隐含地允许多重继承?如果没有,如果我尝试以下操作会发生什么:
public interface A { int Foo() => 1; }
public interface B { int Foo() => 2; }
public class C : A, B { }
根据https://blogs.msdn.microsoft.com/dotnet/2018/11/12/building-c-8-0/,C# 8 中的新功能之一是接口的默认实现。这个新特性是否也隐含地允许多重继承?如果没有,如果我尝试以下操作会发生什么:
public interface A { int Foo() => 1; }
public interface B { int Foo() => 2; }
public class C : A, B { }
Mads Torgersen 在您链接到的博客文章中回答了您的问题:
实际上接口离抽象类还很远。类不从接口继承成员,所以如果一个类留下一个由接口实现的成员 M,则该类没有成员 M!这就像今天的显式实现;您必须转换为界面才能获得此类成员。
所以用你的例子:
public interface A { int Foo() => 1; }
public interface B { int Foo() => 2; }
public class C : A, B { }
你不能做这个:
var something = new C();
var x = something.Foo(); /* does not compile */
您可以执行以下操作:
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 */
感谢@CodeCaster 他/她的精彩评论促成了这个答案。
该提案指出:
请注意,类不会从其接口继承成员;此功能不会改变:
因此,这似乎是合理的(尽管在发货之前无法 100% 确定地确认):
public interface A { int Foo() => return 1; }
public interface B { int Foo() => return 2; }
public class C : A, B { }
会正常工作。
正如提案所示:
new C().M(); // error: class 'C' does not contain a member 'M'
那么我们可以假设您的版本:
new C().Foo();
也不会编译。
该提案显示:
IA i = new C();
i.M();
作为有效,这相当于你的:
A i = new C();
i.Foo();
由于i
被声明为类型,因此没有理由假设如果更改为A
相同将不起作用- 没有可言的冲突。A
B
此功能的全部意义在于允许以安全的方式扩展接口(请参阅此视频)。如果这仅在您实现了一个接口时才有效,那似乎与该功能的目标背道而驰。鉴于该功能似乎以大致类似于显式接口实现的方式实现(这就是我们不能C.Foo()
直接调用的原因),我认为我们可以合理地假设它很可能允许多个接口实现。