C#8默认接口实现是否允许多重继承

时间:2018-11-13 10:10:39

标签: c# oop inheritance c#-8.0

根据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 { }

2 个答案:

答案 0 :(得分:11)

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 */

答案 1 :(得分:6)

感谢@CodeCaster的出色评论,促使他给出了答案。

proposal指出:

  

请注意,类不会从其接口继承成员;那   不会被此功能更改:

因此,似乎合理(尽管在发货之前不可能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,则不会起作用-没有说话冲突的。

此功能的全部目的是允许以安全的方式扩展接口(请参见this video)。如果您仅实现了一个界面,则该起作用,则似乎与该功能的目标背道而驰。鉴于该功能似乎是通过大致类似于显式接口实现的方式实现的(这就是为什么我们不能直接调用C.Foo()的原因),我认为我们可以合理地< / em>假定它很可能会允许多个接口实现。