【问题标题】:C# protected field access [duplicate]C#受保护的字段访问[重复]
【发布时间】:2012-05-26 09:49:06
【问题描述】:

(这个问题是C# accessing protected member in derived class的后续问题)

我有以下代码sn-p:

public class Fox
{
    protected string FurColor;
    private string furType;

    public void PaintFox(Fox anotherFox)
    {
        anotherFox.FurColor = "Hey!";
        anotherFox.furType = "Hey!";
    }
}

public class RedFox : Fox
{
    public void IncorrectPaintFox(Fox anotherFox)
    {
        // This one is inaccessible here and results in a compilation error.
        anotherFox.FurColor = "Hey!";
    }

    public void CorrectPaintFox(RedFox anotherFox)
    {
        // This is perfectly valid.
        anotherFox.FurColor = "Hey!";
    }
}
  • 现在,我们知道private and protected fields are private and protected for type, not instance.

  • 我们也知道访问修饰符应该在编译时起作用。

  • 那么,问题来了 - 为什么我不能访问RedFox 中Fox 类实例的FurColor 字段? RedFox 派生自@ 987654330@,因此编译器知道它可以访问相应的受保护字段。

  • 另外,正如您在CorrectPaintFox 中看到的,我可以访问RedFox 类实例的受保护字段。 那么,为什么我不能对 Fox 类实例有同样的期望呢?

【问题讨论】:

标签: c# private encapsulation protected


【解决方案1】:

原因很简单:

public void IncorrectPaintFox(Fox anotherFox)
{
    anotherFox = new BlueFox();

    // This one is inaccessible here and results in a compilation error.
    anotherFox.FurColor = "Hey!";
}

现在您没有从 BlueFox 中访问受保护的字段,因此由于编译器不知道运行时类型是什么,它必须始终将其设为错误。

【讨论】:

  • +1 人总是忘记同级类...
【解决方案2】:

为了稍微扩展已接受的答案,原因编译器强制执行此规则,而不是 PHP 所具有的 protected 更宽松的含义,因为允许您想要访问allow 可以通过绕过其定义的保护级别来破坏类的不变量。 (当然,这总是可能的,例如通过反射,但编译器至少使得它很难做到意外)。

问题在于,仅仅知道某个对象是 Fox 并不能使您安全地与其内部工作进行交互,因为它可能实际上不是 Fox at 运行。考虑这些类:

public class Fox
{
  protected Color FurColor;
}

public class RedFox
{
  public RedFox () 
  { 
    this.FurColor = Color.Red; 
  }
}

public class ArcticFox
{
  public ArcticFox () 
  { 
    this.FurColor = Color.White; 
  }
}  

您要求编译器允许以下方法,假设它是在 RedFox 类上定义的:

public void PaintFoxRed ( Fox fox )
{
    fox.FurColor = Color.Red;
}

但如果这是合法的,我可以这样做:

RedFox a = new RedFox();
Fox b = new ArcticFox();
a.PaintFoxRed(b);

我的ArcticFox 现在是红色的,尽管班级本身只允许自己是白色的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-18
    • 2019-05-07
    • 2015-05-09
    • 2012-05-26
    相关资源
    最近更新 更多