Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to hide an inherited property in a class without modifying the inherited class (base class)?

If i have the following code example:

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

What should I do to hide the property Name (Don't shown as a member of ClassA members) without modifying ClassBase ?

like image 235
Ahmed Magdy Avatar asked Dec 09 '09 17:12

Ahmed Magdy


People also ask

Is used to hide an inherited member from a base class member?

When used as a declaration modifier, the new keyword explicitly hides a member that is inherited from a base class.

Can you prevent your class from being inherited by another class how?

You can prevent a class from being subclassed by using the final keyword in the class's declaration. Similarly, you can prevent a method from being overridden by subclasses by declaring it as a final method.

Can inherited properties be overridden?

You cannot use the new , static , or virtual modifiers to modify an override method. An overriding property declaration must specify exactly the same access modifier, type, and name as the inherited property. Beginning with C# 9.0, read-only overriding properties support covariant return types.

How do I restrict my inherited class in C#?

In C# you use the sealed keyword in order to prevent a class from being inherited. In VB.NET you use the NotInheritable keyword. In Java you use the keyword final .


2 Answers

I smell a code smell here. It is my opinion that you should only inherit a base class if you're implementing all of the functionality of that base class. What you're doing doesn't really represent object oriented principles properly. Thus, if you want to inherit from your base, you should be implementing Name, otherwise you've got your inheritance the wrong way around. Your class A should be your base class and your current base class should inherit from A if that's what you want, not the other way around.

However, not to stray too far from the direct question. If you did want to flout "the rules" and want to continue on the path you've chosen - here's how you can go about it:

The convention is to implement the property but throw a NotImplementedException when that property is called - although, I don't like that either. But that's my personal opinion and it doesn't change the fact that this convention still stands.

If you're attempting to obsolete the property (and it's declared in the base class as virtual), then you could either use the Obsolete attribute on it:

[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: As Brian pointed out in the comments, the second parameter of the attribute will cause a compiler error if someone references the Name property, thus they won't be able to use it even though you've implemented it in derived class.)

Or as I mentioned use NotImplementedException:

public override string Name {     get     {         throw new NotImplementedException();     }     set     {         throw new NotImplementedException();     } } 

However, if the property isn't declared as virtual, then you can use the new keyword to replace it:

public new string Name {     get     {         throw new NotImplementedException();     }     set     {         throw new NotImplementedException();     } } 

You can still use the Obsolete attribute in the same manner as if the method was overridden, or you can throw the NotImplementedException, whichever you choose. I would probably use:

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

or:

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

Depending on whether or not it was declared as virtual in the base class.

like image 190
BenAlabaster Avatar answered Sep 27 '22 22:09

BenAlabaster


While technically the property won't be hidden, one way to strongly discourage its use is to put attributes on it like these:

[Browsable(false)] [Bindable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [EditorBrowsable(EditorBrowsableState.Never)] 

This is what System.Windows.Forms does for controls that have properties that don't fit. The Text property, for instance, is on Control, but it doesn't make sense on every class that inherits from Control. So in MonthCalendar, for instance, the Text property appears like this (per the online reference source):

[Browsable(false),     EditorBrowsable(EditorBrowsableState.Never),     Bindable(false),      DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override string Text {     get { return base.Text; }     set { base.Text = value; } } 
  • Browsable - whether the member shows up in the Properties window
  • EditorBrowsable - whether the member shows up in the Intellisense dropdown

EditorBrowsable(false) won't prevent you from typing the property, and if you use the property, your project will still compile. But since the property doesn't appear in Intellisense, it won't be as obvious that you can use it.

like image 30
Ryan Lundy Avatar answered Sep 27 '22 21:09

Ryan Lundy