这段代码:
abstract class C { protected abstract void F(D d); } class D : C { protected override void F(D d) { } void G(C c) { c.F(this); } }
产生此错误:
无法通过类型“ C”的限定符访问受保护成员“ CF(D)”;限定词必须为“ D”类型(或从其派生)
他们在想什么?(改变该规则会破坏某些东西吗?)除了公开F之外,还有其他方法吗?
编辑:我现在知道为什么这是为什么(谢谢Greg),但是对于理性我还是有些困惑;给出:
class E : C { protected override void F(D d) { } }
为什么 不应该 D是能够能够调用EF?
错误消息已编辑,因此我可能在其中输入了错字。
“保护”关键字意味着只有一种类型和从该类型派生的类型可以访问成员。D与C没有关系,因此无法访问该成员。
如果您希望能够访问该成员,则有两种选择
编辑
这种情况在C#规范的3.5.3节中提到。
不允许这样做的原因是因为它将允许跨层次调用。想象一下,除了D之外,还有C的另一个基类E,如果您的代码可以编译,它将允许D访问成员EF。这种情况在C#中是不允许的(而且我 相信 CLR,但是我不这样做) t 100%知道)。
EDIT2 为什么这很糟糕
请注意,这是我的意见
现在允许这样做的原因是,这使得很难对类的行为进行推理。访问修饰符的目的是使开发人员完全控制谁可以访问特定方法。想象以下课程
sealed class MyClass : C { override F(D d) { ... } }
考虑一下如果F是一个时间紧迫的函数会发生什么。通过当前行为,我可以推断出我班级的正确性。毕竟只有两种情况会调用MyClass.F。
我可以检查这些调用并就MyClass的功能得出合理的结论。
现在,如果C#确实允许跨层次结构保护的访问,则我无法做出任何保证。完全不同的程序集中的任何人都可以从C派生而来。然后他们可以随意调用MyClass.F。这使得完全不可能推理出我班级的正确性。