C# 8 默认接口实现是否允许多重继承
Do C# 8 default interface implementations allow for multiple inheritance
根据 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 { }
感谢@CodeCaster 的 his/her 提示此答案的精彩评论。
proposal 状态:
Note that a class does not inherit members from its interfaces; that
is not changed by this feature:
因此,这似乎是合理的(尽管在发货之前无法 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)。如果这个 只有 在你实现一个接口的情况下起作用,那似乎与该功能的 objective 相悖。考虑到该功能似乎以一种 大致 类似于显式接口实现的方式实现(这就是我们不能直接调用 C.Foo()
的原因),我认为我们可以 合理地假设它很可能允许多个接口实现。
Mads Torgersen 在您链接到的博客 post 中回答了您的问题:
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.
以你的例子为例:
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 */
根据 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 { }
感谢@CodeCaster 的 his/her 提示此答案的精彩评论。
proposal 状态:
Note that a class does not inherit members from its interfaces; that is not changed by this feature:
因此,这似乎是合理的(尽管在发货之前无法 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)。如果这个 只有 在你实现一个接口的情况下起作用,那似乎与该功能的 objective 相悖。考虑到该功能似乎以一种 大致 类似于显式接口实现的方式实现(这就是我们不能直接调用 C.Foo()
的原因),我认为我们可以 合理地假设它很可能允许多个接口实现。
Mads Torgersen 在您链接到的博客 post 中回答了您的问题:
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.
以你的例子为例:
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 */