Roy*_*oof 18 c# oop inheritance c#-8.0 default-interface-member
根据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 { }
Run Code Online (Sandbox Code Playgroud)
use*_*702 15
Mads Torgersen在您链接到的博客文章中回答了您的问题:
实际上,接口与抽象类相距甚远.类不从接口继承成员,因此如果一个类留下由接口实现的成员M,则该类没有成员M!这就像今天的明确实施; 你必须转换到界面才能获得这些成员.
以你的例子为例:
public interface A { int Foo() => 1; }
public interface B { int Foo() => 2; }
public class C : A, B { }
Run Code Online (Sandbox Code Playgroud)
你不能做这个:
var something = new C();
var x = something.Foo(); /* does not compile */
Run Code Online (Sandbox Code Playgroud)
您可以执行以下操作:
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 */
Run Code Online (Sandbox Code Playgroud)
感谢@CodeCaster提供了他/她的好评,这些评论促成了这个答案.
该提案指出:
请注意,类不会从其接口继承成员; 这个功能没有改变:
因此,它似乎是合理的(虽然在发货前100%确定无法确认):
public interface A { int Foo() => return 1; }
public interface B { int Foo() => return 2; }
public class C : A, B { }
Run Code Online (Sandbox Code Playgroud)
会很好的.
正如提案显示:
new C().M(); // error: class 'C' does not contain a member 'M'
Run Code Online (Sandbox Code Playgroud)
那么我们可以假设你的版本:
new C().Foo();
Run Code Online (Sandbox Code Playgroud)
也不会编译.
该提案显示:
IA i = new C();
i.M();
Run Code Online (Sandbox Code Playgroud)
有效,相当于你的:
A i = new C();
i.Foo();
Run Code Online (Sandbox Code Playgroud)
由于i被声明为类型A,没有理由认为如果A更改为相同则不起作用B- 没有冲突可言.
此功能的重点是允许以安全的方式扩展接口(请参阅此视频).如果只有在实现了一个界面时才有效,那么这似乎与该功能的目标相反.而鉴于该功能出现在办法实施大致类似于显式接口实现(这就是为什么我们不能调用C.Foo()直接),我认为我们可以合理地假设,它很可能会允许多个接口的实现.