Bas*_*ili 10 c# c#-8.0 default-interface-member
为什么默认接口方法的行为在 C# 8 中发生了变化?过去的以下代码(当默认接口方法未发布时):
interface IDefaultInterfaceMethod
{
// By default, this method will be virtual, and the virtual keyword can be here used!
virtual void DefaultMethod()
{
Console.WriteLine("I am a default method in the interface!");
}
}
interface IOverrideDefaultInterfaceMethod : IDefaultInterfaceMethod
{
void IDefaultInterfaceMethod.DefaultMethod()
{
Console.WriteLine("I am an overridden default method!");
}
}
class AnyClass : IDefaultInterfaceMethod, IOverrideDefaultInterfaceMethod
{
}
class Program
{
static void Main()
{
IDefaultInterfaceMethod anyClass = new AnyClass();
anyClass.DefaultMethod();
IOverrideDefaultInterfaceMethod anyClassOverridden = new AnyClass();
anyClassOverridden.DefaultMethod();
}
}
Run Code Online (Sandbox Code Playgroud)
有以下输出:
控制台输出:
我是界面中的默认方法!
我是一个被覆盖的默认方法!
但是对于 C# 8 的最后一个版本,上面的代码会产生以下输出:
控制台输出:
我是一个被覆盖的默认方法!
我是一个被覆盖的默认方法!
任何人都可以向我解释为什么这种行为会改变?
笔记:
IDefaultInterfaceMethod anyClass = new AnyClass(); anyClass.DefaultMethod();
((IDefaultInterfaceMethod) anyClass).DefaultMethod(); // STILL the same problem!??
Run Code Online (Sandbox Code Playgroud)
我怀疑一个更好的问题是:
如何调用默认方法而不是具体实现?
该功能是计划中的,但在 2019 年 4 月从 C# 8 中删除,因为有效的实现需要运行时的支持。这在发布之前无法及时添加。该功能必须同时适用于 C# 和 VB.NET - F# 无论如何都不喜欢接口。
如果运行时 BM 不存在,则将调用 AM()。对于 base() 和接口,运行时不支持,因此调用将抛出异常。我们想在运行时添加对此的支持,但发布此版本的成本太高了。
我们有一些解决方法,但它们没有我们想要的行为,也不是首选的代码生成器。
我们对 C# 的实现在某种程度上是可行的,虽然不完全是我们想要的,但是 VB 实现会困难得多。此外,VB 的实现将要求接口实现方法是公共 API 表面。
它将通过base()类似于类工作方式的调用来工作。复制提案示例:
interface I1
{
void M(int) { }
}
interface I2
{
void M(short) { }
}
interface I3
{
override void I1.M(int) { }
}
interface I4 : I3
{
void M2()
{
base(I3).M(0) // What does this do?
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
891 次 |
| 最近记录: |