Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#中实例成员的受保护访问?_C#_.net_Protected - Fatal编程技术网

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

C#中实例成员的受保护访问?,c#,.net,protected,C#,.net,Protected,可能重复: 当我在读一本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;

可能重复:

当我在读一本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
    }
}
查看受保护的含义:

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

问题

  • 为什么存在这种限制(通过实例)

  • 您能否提供一个有问题的情况的例子,就好像这是允许的一样


    • 这是对第二个问题的一个很好的回答

      此限制阻止一个派生类访问其他派生类的受保护成员 派生类,即使成员是从同一基类继承的

      下面是现有问题的链接


      您引用的受保护含义不是技术定义,而是规范引用的直观含义(第3.5.1节):

      受保护的直观含义是“仅限用户访问” 包含类或从包含类派生的类型”

      在同一节中,它给出了更严格的定义(这里M是T型的成员):

      否则,如果M受到保护,则允许访问 在声明M的类中,或者如果它发生在 从声明并发生M的类派生的类 通过派生类类型(§3.5.3)

      参考章节(3.5.3)专门介绍受保护的成员访问,并包含您的示例和注释:

      此限制阻止一个派生类访问受保护的 其他派生类的成员,即使这些成员是继承的 来自同一个基类

      因此,答案是明确的。它的目的是防止第三类人做这样的事情:

      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
        }
      }
      

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

      这是一个msdn示例,并删除了重要部分:在a中,可以通过a和B的实例访问x,因为在这两种情况下,访问都是通过A的实例或从A派生的类进行的。但是,在B中,不可能通过A的实例访问x,因为A不是从B派生的。如果通过C.x=从B派生C,而不是通过A,则甚至可以操纵x。您可以访问当前的类实例变量,而不是所说的父类实例