C#中实例成员的受保护访问?

3
可能是重复问题: 为什么我不能像这样访问C#受保护的成员? 当我阅读一本c#书籍时(这本书有特殊注释版,显示了c#的所有棘手部分),我看到了这段代码:
public class A
{
    protected int x;
    static void F(A a, B b)
    {
        a.x = 1; // Okay
        b.x = 1; // Okay
    }
}
public class B: A
{
    static void F(A a, B b)
    {
        a.x = 1; // Error: must access through instance of B
        b.x = 1; // Okay
    }
}

protected的意思:

仅限于此类或从此类派生的类的访问权限

问题

  • 为什么要存在这个(通过实例)的限制?

  • 您能否提供一个禁止后会导致问题的情况的例子?


这是一个MSDN的例子,已经删除了重要部分:在A中,可以通过A的实例或从A派生的类的实例来访问x,因为访问都是通过A的实例或从A派生的类的实例进行的。然而,在B中,不可能通过A的实例来访问x,因为A不是从B派生的。即使通过从B派生C的方式进行c.x = 操作也可以操作x,但不能通过a进行。在当前类实例变量方面,您可以访问当前类实例变量,而非父类的实例变量。 - Najzero
2个回答

2
你所引用的protected的意义并不是技术定义,而仅仅是规范引用的直观意义(第3.5.1节):
“protected的直观含义是'访问限制于包含类或派生自包含类的类型'。”
在同一节中,它提供了更严谨的定义(这里M是类型T的成员):
“否则,如果M是protected,则允许访问,如果它发生在声明M的类内部,或者如果它发生在从声明M的类派生的类内部,并且通过派生类类型进行(§3.5.3)。 ”
所引用的第3.5.3节特别涉及protected成员访问,并包含您的示例和注释:
“此限制防止一个派生类访问其他派生类的受保护成员,即使这些成员是从相同的基类继承而来。”
因此答案很明确。 它旨在防止第三个类执行以下操作:
public class C : A
{
  public static void F(A a, B b, C c)
  {
     a.x = 1; // not allowed
     b.x = 1; // not allowed
     c.x = 1; // allowed
  }
}

根据您对protected的定义,前两个赋值是允许的。这可能有点奇怪。假设我有我的库并定义了AB,但我允许您从A继承并编写C。作为一个库作者,我会有点担心,因为有人可以修改我编写的类实例的内部细节!当然,您可以通过属性或方法公开对C中字段x的修改,但该行为仅限于您的类C的实例。


1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接