【问题标题】:C# protected members accessed via base class variable [duplicate]通过基类变量访问的 C# 受保护成员 [重复]
【发布时间】:2010-12-22 14:41:40
【问题描述】:

这似乎是一个新手问题,但你能解释一下为什么方法 Der.B() 不能通过基类变量访问受保护的 Foo 吗?我觉得这很奇怪:

public class Base
{
    protected int Foo;
}

public class Der : Base
{
    private void B(Base b) { Foo = b.Foo; } // Error: Cannot access protected member

    private void D(Der d) { Foo = d.Foo; } // OK
}

谢谢!

【问题讨论】:

    标签: c# inheritance protected base-class


    【解决方案1】:

    您可以通过在基类中声明一个静态方法来解决此限制:

    public class Base
    {
        protected int Foo;
    
        protected static int GetFoo(Base b)
        {
            return b.Foo;
        }
    }
    
    public class Der : Base
    {
        private void B(Base b) { Foo = GetFoo(b); } // OK
    }

    【讨论】:

      【解决方案2】:

      简单地说,protected 允许访问子类。

      在:

      private void B(Base b) { Foo = b.Foo; }
      

      您正在尝试访问您的 Der 实例无权访问的受保护成员。只有当它是当前 Der 实例的基类时,它才能访问它(this)。

      private void D(Der d) { Foo = d.Foo; } // OK
      

      工作正常,因为您正在通过 Der 访问它的基类受保护方法。

      【讨论】:

      • 我想你的意思是说:private void D(Der d) { Foo = d.Foo; } 工作正常。有点令人困惑的 b/c 你复制了这行代码。
      • 糟糕,我的意思是复制第二个代码示例。
      【解决方案3】:

      在您尝试的场景中,您将希望对 int Foo 使用“内部”。

      【讨论】:

      • 如果 B 传递的是 Base 而不是 Der,这将不起作用。
      • 我知道我可以使用 internal 甚至 public 而不是 protected。但我想了解为什么受保护的行为就像帖子中描述的那样。
      • @Roman:因为 protected 只对 Derived 类可见。在同一个实例内。但是您正试图从不同的实例中查看它。如果可以做到这一点,protected 将毫无用处。
      • @Roman - RagePotato 回答了这个问题。
      • 尤里是正确的。我发布的代码是垃圾。哈哈。我删除了它。 Eric Lippert 的回答是正确的,此外,我想知道您为什么要这样做而不是内部化?
      【解决方案4】:

      这是一个常见问题。要弄清楚为什么这是非法的,请想想可能出了什么问题。

      假设您有另一个从 Base 派生的派生类 Frob。现在您将 Frob 的一个实例传递给 Der.B。您应该能够从 Der.B 访问 Frob.Foo 吗?不,绝对不是。 Frob.Foo 受到保护;它应该只能从 Frob 和 Frob 的子类访问。 Der 不是 Frob,也不是 Frob 的子类,因此它无法访问 Frob 的受保护成员。

      如果不清楚,请参阅我关于该主题的文章:

      http://blogs.msdn.com/ericlippert/archive/2005/11/09/491031.aspx

      【讨论】:

      • 谢谢。我现在清楚了。
      【解决方案5】:

      在 B 中,您试图访问另一个类的受保护成员。您从该类继承的事实是无关紧要的。在 D 中,您正在访问当前类的基类的受保护成员。在这种情况下,您可以从 Der 及其继承的类型的受保护成员中访问任何内容。

      【讨论】:

      • +1 进行解释,但我仍然怀疑为什么“您从该类继承的事实无关紧要”?它是规范谓词吗?
      • 如果有人初始化了 Der,您从它继承的事实使您可以访问它。在这种情况下,您可以将其转换为 Der,然后访问 Foo。
      猜你喜欢
      • 2016-10-01
      • 2012-11-20
      • 2016-07-15
      • 2019-08-27
      • 2011-03-29
      • 2012-05-26
      • 2014-01-26
      • 2017-03-19
      相关资源
      最近更新 更多