【问题标题】:How to hide inherited property?如何隐藏继承财产?
【发布时间】:2018-07-18 05:16:41
【问题描述】:

我正在尝试让一个类继承自另一个我无权访问的类。

public class MyLabel : Label
{
    public MyLabel()
    {
        base.Text = "This text is fixed";
        base.BackgroundColor = Color.Green;
    }
}

当像这样调用时,TextVisible 属性仍然可用:

MyLabel lbl = new MyLabel();
lbl.Text = "Nope.";
lbl.BackgroundColor = Color.Red;

有没有办法使这两个最后的语句无效?

【问题讨论】:

标签: c# .net class inheritance properties


【解决方案1】:

继承就是继承。如果你的父母把蓝眼睛的特性传给你,那么这个特性就在你的遗传密码中。不过,这并不意味着你有蓝眼睛。当您继承该特征时,您可能有棕色的眼睛(主要特征),因此您会表达该特征。

代码的工作方式类似。如果foo 继承自bar,则每个foo 都将具有bar 的特征。但是,您可以做的是用该类独有的特征覆盖特征。

  public override string Text
  {
            get { return "Nope"; }    
            set { return; /*or throw an exception or whatever you want to do*/ }
  }

现在我已经向您展示了如何,如果可以避免,请不要这样做。如果您担心继承像 Label 这样的复杂对象,并且不想公开它继承的某些内容,那么您的问题可能与属性上的修饰符无关,而与实际实例上的范围修饰符。您最好在更窄的范围内使用该对象,然后在其他任何东西访问它之前让它超出范围。

您要避免这种情况的原因是代码异味。假设您创建了一个使用 MyLabel 的类库。因为它继承自Label,所以我知道我可以像使用标签一样使用它。然后,当我这样做时:

MyLabel myLanta = new MyLabel();
myLanta.Text = "Oh!";

...然后我将继续花一个小时试图找出为什么 myLanta 的文本总是“不!”这就是为什么在这里抛出异常很重要,或者至少使用摘要,这样当另一个人在编码时,他们可以一眼看出无论他们为“文本”分配什么,它总是“不”。

我的建议是,如果您需要缩小类的可用属性,使该类成为新类的组件,而不是继承它

public class MyLabel
{
    private System.Windows.Forms.Label label 
    = new System.Windows.Forms.Label { Text = "Nope", BackColor = Color.Green };
    //a public accessor and setter
    public Font Font { get { return label.Font; } set { label.Font = value; } }     
    //only this class can set the color, any class can read the color
    public Color ForeColor { get { return label.ForeColor; } private set { label.ForeColor = value; } }
    public AllMyStuffIWantToDo()....
    //fill in your stuff here
}

然后,如果您想返回Label 的属性,您可以使用您控制的方法和属性,而不必担心继承问题。如果您不提供对Label 属性的访问方法,则该属性永远不会出现,并且实际上是类私有的。这还可以防止有人通过您的MyLabel 代替Forms.Label 传递损坏的代码,因为该继承合同将不存在。

【讨论】:

  • 这是一个很好的答案,但我需要复制我想在外面使用的每一个属性。所以这对我不起作用。但很好的答案!当然它对其他程序员有用。
【解决方案2】:

您可以使用 new 关键字隐藏继承的属性并将它们重新定义为只读。

public class MyLabel : Label
{
    new public string Text { get { return base.Text; } }
    new public string BackColor { get { return base.BackColor; } }

    public MyLabel()
    {
        base.Text = "This text is fixed";
        base.BackColor= Color.Green;
    }
}

【讨论】:

  • 我也在尝试“新”。但我很惊讶为什么仍然允许“新的私有字符串文本”?我的意思不是作为属性....只是声明为变量....但是私有在那里无效....
  • 据我所知,如果您更改访问修饰符,您将不会隐藏继承的属性。哦,我明白你的意思了……只是事实是允许的。
  • 并不是说这是错误的,但请记住在使用new:stackoverflow.com/a/1399151/68432 时有一些微妙的“陷阱”。即“任何不引用你的类但父类的代码都将使用父类实现。
  • @npearson 我明白了,但是编译器应该首先尊重本地私有变量 rt.... :) :)..... 但是我看到值不能分配给对象... . 它只是说 Null,即使分配了一些值
猜你喜欢
  • 1970-01-01
  • 2013-02-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 2012-02-13
  • 1970-01-01
相关资源
最近更新 更多