public class A
{
protected virtual int X {get; private set;}
}
public class B : A
{
public int Add(A other)
{
return X + other.X;
}
}
Run Code Online (Sandbox Code Playgroud)
因为如果是,你有这个:
public class C : A
{
protected override int X { get { return 4; } }
}
Run Code Online (Sandbox Code Playgroud)
然后:
A c = new C();
B b = new B();
b.Add(c);
Run Code Online (Sandbox Code Playgroud)
这是非法的,因为即使B访问X意味着它知道C具有所需的签名,它仍然不允许实际访问该成员.
到现在为止还挺好.但鉴于上述情况,我很困惑的是为什么我能做到这一点:
public class A
{
protected virtual int X { get; private set; }
public int Add(A other)
{
return X + other.X;
}
}
Run Code Online (Sandbox Code Playgroud)
因此,这个:
A c = new C();
A a = new A();
a.Add(c);
Run Code Online (Sandbox Code Playgroud)
受保护的成员可在其类和派生类实例中访问.
但是现在受保护的成员on C是从内部访问的A,既不是"它的类"也不是"派生类实例",而是父类.虽然A显然可以访问签名,但兄弟姐妹的例子似乎表明仅仅这一点不应该足够,那么为什么protected授予它访问该成员呢?
这由规范定义:
当在声明它的类的程序文本之外访问受保护的实例成员时,并且当在声明它 的程序的程序文本之外访问受保护的内部实例成员时,需要通过发生访问的派生类类型的实例.:
public class A
{
protected int x;
static void F(A a, B b)
{
a.x = 1; // Ok
b.x = 1; // Ok
}
}
public class B : A
{
static void F(A a, B b)
{
a.x = 1; // Error, must access through instance of B
b.x = 1; // Ok
}
}
Run Code Online (Sandbox Code Playgroud)
在A中,可以通过A和B的实例访问x,因为在任何一种情况下,访问都是通过A的实例或从A派生的类进行的.但是,在B中,不可能通过A访问x A的一个实例,因为A不是从B派生的
这一点的全部意义在于,我不希望任何类的人C,尽管允许从我的班级派生,在课堂上A访问我的"内部"状态B,尽管他们都分享了他们是类的衍生物这一事实A.
作为 的作者C,我可以选择我的基类。所以我发现A,我已经阅读了它的文档,我知道它如何以及为什么会调用我继承的任何protected成员(当然,我有一些选项,例如sealed或保护我的构造函数来控制哪些类(如果有的话)可以源自我的C)。这就是我真正需要考虑的所有问题(在反射/完全控制场景之外,但是一旦反射出现在图片中,所有的赌注都会消失)。
我不必担心其他人决定他们想要调用这些protected方法。(根据您建议的修改),他们只需创建自己的类 ,B派生自A.
| 归档时间: |
|
| 查看次数: |
222 次 |
| 最近记录: |