C# 如何在不修改继承的类(基类)的情况下隐藏类中的继承属性?

C# 如何在不修改继承的类(基类)的情况下隐藏类中的继承属性?,c#,inheritance,properties,base-class,C#,Inheritance,Properties,Base Class,如果我有以下代码示例: public class ClassBase { public int ID { get; set; } public string Name { get; set; } } public class ClassA : ClassBase { public int JustNumber { get; set; } public ClassA() { this.ID = 0; this.Name

如果我有以下代码示例:

public class ClassBase
{
    public int ID { get; set; }

    public string Name { get; set; }
}

public class ClassA : ClassBase
{
    public int JustNumber { get; set; }

    public ClassA()
    {
        this.ID = 0;
        this.Name = string.Empty;
        this.JustNumber = string.Empty;
    }
}

我应该如何隐藏属性
Name
(不显示为ClassA成员的成员),而不修改
ClassBase

你不能,这就是继承的全部要点:子类必须提供基类的所有方法和属性


您可以将实现更改为在调用属性时引发异常(如果它是虚拟的).

我在这里闻到了代码的味道。我认为,只有在实现基类的所有功能时,才应该继承该基类。您所做的并不能正确地表示面向对象的原则。因此,如果您想从基础继承,那么应该实现Name,否则您的继承方式就错了。你的类A应该是你的基类,你当前的基类应该继承自A,如果这是你想要的,而不是相反

但是,不要偏离直接的问题太远。如果你真的想藐视“规则”,想继续走你选择的道路——以下是你可以做到的:

约定是实现该属性,但在调用该属性时抛出NotImplementedException——尽管我也不喜欢这样。但这是我个人的观点,这并不能改变这个公约仍然存在的事实

如果您试图废弃该属性(并且该属性在基类中声明为虚拟属性),则可以对其使用obsolete属性:

[Obsolete("This property has been deprecated and should no longer be used.", true)]
public override string Name 
{ 
    get 
    { 
        return base.Name; 
    }
    set
    {
        base.Name = value;
    }
}
Edit:正如Brian在评论中指出的,如果有人引用Name属性,该属性的第二个参数将导致编译器错误,因此即使您在派生类中实现了它,他们也无法使用它。)

或者,正如我提到的,使用NotImplementedException:

public override string Name
{
    get
    {
        throw new NotImplementedException();
    }
    set
    {
        throw new NotImplementedException();
    }
}
但是,如果属性未声明为虚拟,则可以使用new关键字替换它:

public new string Name
{
    get
    {
        throw new NotImplementedException();
    }
    set
    {
        throw new NotImplementedException();
    }
}
您仍然可以像重写方法一样使用过时属性,或者可以抛出NotImplementedException,无论您选择哪个。我可能会使用:

[Obsolete("Don't use this", true)]
public override string Name { get; set; }
或:


取决于它是否在基类中声明为虚拟。

从技术上讲,该属性不会被隐藏,但强烈反对使用它的一种方法是在其上放置如下属性:

[Browsable(false)]
[Bindable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[EditorBrowsable(EditorBrowsableState.Never)]
这就是System.Windows.Forms对属性不合适的控件所做的。例如,Text属性位于控件上,但它对从控件继承的每个类都没有意义。例如,在中,文本属性如下所示(根据在线参考源):

  • 可浏览-成员是否显示在属性窗口中
  • EditorBrowsable-成员是否显示在Intellisense下拉列表中
EditorBrowsable(false)不会阻止您键入属性,如果您使用该属性,您的项目仍将编译。但是,由于该属性没有出现在Intellisense中,因此您不能很明显地使用它。

只需隐藏它即可

 public class ClassBase
{
    public int ID { get; set; }
    public string Name { get; set; }
}
public class ClassA : ClassBase
{
    public int JustNumber { get; set; }
    private new string Name { get { return base.Name; } set { base.Name = value; } }
    public ClassA()
    {
        this.ID = 0;
        this.Name = string.Empty;
        this.JustNumber = 0;
    }
}

注意:Name仍然是ClassBase的公共成员,考虑到不更改基类的限制,没有办法阻止它。

为什么在不需要继承时强制继承? 我认为正确的做法是做has-a而不是is-a

public class ClassBase
{
    public int ID { get; set; }

    public string Name { get; set; }
}

public class ClassA
{
    private ClassBase _base;

    public int ID { get { return this._base.ID; } }

    public string JustNumber { get; set; }

    public ClassA()
    {
        this._base = new ClassBase();
        this._base.ID = 0;
        this._base.Name = string.Empty;
        this.JustNumber = string.Empty;
    }
}

我认为这里的很多人根本不理解继承。需要从基类继承并隐藏其曾经公开的var和函数。例如,假设你有一个基本的发动机,你想制造一个新的增压发动机。好吧,99%的引擎你会使用,但你会调整一点它的功能,使其运行得更好,但仍然有一些功能,应该只显示给修改,而不是最终用户。因为我们都知道MS推出的每个类实际上并不需要任何修改

除了使用新功能来简单地覆盖功能之外,这也是微软在其无限智慧中所做的事情之一…。。哦,我的意思是错误被认为不再是一种值得使用的工具

现在实现这一点的最佳方法是多级继承

public class classA 
{
}

public class B : A 
{} 

public class C : B 
{} 

B类完成您的所有工作,C类公开您需要公开的内容

我认为如果必须这样做,那么设计就很糟糕,尤其是如果你能够从头开始设计代码的话

为什么?

好的设计是让基类共享某个概念具有的公共属性(虚拟或真实)。示例:C#中的System.IO.Stream

再往下走,糟糕的设计将增加维护成本,使实施变得越来越困难。尽量避免这种情况

我使用的基本规则:

  • 最小化基类中属性和方法的数量。如果您不希望在继承基类的类中使用某些属性或方法;那么不要把它放在基类中。如果您处于项目的开发阶段;总是回到绘图板上,然后检查设计,因为事情发生了变化!需要时重新设计。当你的项目是活的成本为改变东西在以后的设计将上升

      >P>如果您使用的是由3:RD党实现的BaseCLASS,请考虑“上行”一个级别,而不是“NoTimPrimeNeTestExpCup”的“覆盖”。如果没有其他级别,请考虑从头开始设计代码。

      总是考虑密封类,你不希望任何人能够继承它。它迫使编码人员在“继承层次结构”中“上一级”,因此可以避免像“NotImplementedException”这样的“松散结尾”


    • 我知道这个问题很老了,但是w
      public class ClassBase
      {
          public int ID { get; set; }
      
          public string Name { get; set; }
      }
      
      public class ClassA
      {
          private ClassBase _base;
      
          public int ID { get { return this._base.ID; } }
      
          public string JustNumber { get; set; }
      
          public ClassA()
          {
              this._base = new ClassBase();
              this._base.ID = 0;
              this._base.Name = string.Empty;
              this.JustNumber = string.Empty;
          }
      }
      
      public class classA 
      {
      }
      
      public class B : A 
      {} 
      
      public class C : B 
      {} 
      
       protected override void PostFilterProperties(System.Collections.IDictionary properties)
          {
              properties.Remove("AccessibleDescription");
              properties.Remove("AccessibleName");
              properties.Remove("AccessibleRole");
              properties.Remove("BackgroundImage");
              properties.Remove("BackgroundImageLayout");
              properties.Remove("BorderStyle");
              properties.Remove("Cursor");
              properties.Remove("RightToLeft");
              properties.Remove("UseWaitCursor");
              properties.Remove("AllowDrop");
              properties.Remove("AutoValidate");
              properties.Remove("ContextMenuStrip");
              properties.Remove("Enabled");
              properties.Remove("ImeMode");
              //properties.Remove("TabIndex"); // Don't remove this one or the designer will break
              properties.Remove("TabStop");
              //properties.Remove("Visible");
              properties.Remove("ApplicationSettings");
              properties.Remove("DataBindings");
              properties.Remove("Tag");
              properties.Remove("GenerateMember");
              properties.Remove("Locked");
              //properties.Remove("Modifiers");
              properties.Remove("CausesValidation");
              properties.Remove("Anchor");
              properties.Remove("AutoSize");
              properties.Remove("AutoSizeMode");
              //properties.Remove("Location");
              properties.Remove("Dock");
              properties.Remove("Margin");
              properties.Remove("MaximumSize");
              properties.Remove("MinimumSize");
              properties.Remove("Padding");
              //properties.Remove("Size");
              properties.Remove("DockPadding");
              properties.Remove("AutoScrollMargin");
              properties.Remove("AutoScrollMinSize");
              properties.Remove("AutoScroll");
              properties.Remove("ForeColor");
              //properties.Remove("BackColor");
              properties.Remove("Text");
              //properties.Remove("Font");
          }
      
      [Browsable( false )]
      public override string Name
      {
          get { return base.Name; }
          set { base.Name= value; }
      }