c# - 为什么 C# 允许我将默认接口实现声明为“密封”,但当我这样做时行为不一致?
问题描述
新的 C# .NET Core 控制台应用程序:
using System;
namespace Interface_Sealed
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new C().X);
Console.WriteLine((new C() as I).X);
Console.ReadKey();
}
interface I
{
sealed int X => 0;
}
class C: I
{
public int X => 1;
}
}
}
运行时,这会将“10”打印到控制台。第一个“.X”是调用类 C 中 X 的实现,第二个是调用接口 I 上的默认实现。
为什么 C# 允许我将 X 的默认实现声明为“密封”,然后允许我用不同的实现覆盖它而不抱怨?为什么我通过类型 I 或类型 C 的引用访问 X 会有所不同?
注意。如果您在 C 中显式而不是隐式实现 IX,则会得到 CS0539“在可实现的接口成员中找不到显式接口声明中的‘Program.CX’”。此错误的 Microsoft 文档页面指出,当“尝试 [is] 显式声明不存在的接口成员”时会发生此错误。好吧,这不是真的,是吗?它确实存在。
解决方案
为什么 C# 允许我将 X 的默认实现声明为“密封”,然后允许我用不同的实现覆盖它而不抱怨?
它没有。您没有覆盖该成员,只是创建了一个具有相同名称的新成员。当类型是接口类型时1
不调用返回的成员这一事实证明了这一点。这与从另一个继承的类中的密封成员完全一致。您并没有阻止实现接口的类拥有具有该名称和签名的自己的成员,您只是阻止它成为与接口(或基类)关联的类。
为什么我通过类型 I 或类型 C 的引用访问 X 会有所不同?
因为两者I
都有C
两个不同的成员,碰巧有相同的名称和签名,但行为不同。只有当您能够覆盖接口的成员时,它们才会具有相同的行为,从而在通过接口调用时更改成员的行为。
好吧,这不是真的,是吗?
不,这是真的。该成员不是可以实现的成员,因为它是密封的。该成员在那里,但您不能更改它的实现,因此会出现错误。
推荐阅读
- python - 我无法从我的数据框中删除没有值的行,为什么?
- windows - 使用什么系统颜色来突出显示 delphi/windows 中的必填字段
- apache-kafka - IllegalStateException: No entry found for connection 是 KafkaConsumer.poll 的可恢复异常吗?
- python - 如何从 vscode 在 cmd 中运行 python 文件
- java - 如何在 JPA 中定义插入时间?
- java - 如何更改从 Scene Builder 制作的按钮的颜色?
- python - 测试值后的 Keras 预测
- mongodb - mongodb中的索引 - 相关字段的一个或两个索引
- android - Android:主动订阅降低价格是否需要用户同意?
- excel - 在 PowerQuery M 中从日期范围(开始日期、结束日期)和年份中获取日期