How to Hide an Inherited Property in a Class Without Modifying the Inherited Class (Base Class)

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

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.

How to hide inherited property?

You can hide the inherited properties using the new keyword and redefine them as readonly.

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

How to restrict the field not to edit in derived class in c#

You could make use of property with private set as follows:

class A
{
public string Name
{
get;
private set;
}
}

class B:A
{
public B()
{
this.Name = "Derived"; // This will not work. If you want to prevent the derived class from accessing the field, just mark the field as private instead of public.
}
}

Hide inherited properties on a class/interface?

You are misinterpreting the idea of inheritance: Basically when you have two classes A and B, and B is an exension of A, B will inherit all non-private elements of A; this is no different if you were using an interace and a class, two interfaces, etc.

Therefore in my opinion you should only use inheritance if you implement all fields, else you kind of defeat the purpose of inheritance and you're not following the object oriented principles.

What you can do however (not the best option, but it is possible) is use:

thow new NotImplementedException();

This make show to the end-programmer that he/she cannot use this property, as his or her application will throw an exception in the debugging stage.

Similarly you can use [Obsolete(..., true)], which will make the compiler throw an error on compiling; note the second parameter is set to true. Also, you can use [Browsable(false)] to hide it in IntelliSense, but this will still allow use of this property.


You can add this to a property, which will effectively disable most usages of your property. It will not actually hide it in the sense you want, but it does show a developer to ignore it.

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

As far as actually hiding it goes, I don't think there is a possibility for that.

hiding property from derived class

Make the Name property virtual in the base Person class. In derived Spy class, override the property and throw Exception in getter.

public class Person
{
public virtual string Name { get; set; }
}

public class Spy : Person
{
public override string Name
{
get
{
throw new Exception("You never ask for a spy's name!");
}
set
{
base.Name = value;
}
}
}

But, rather than throwing exception, I'd suggest something like

get
{
return "**********";
}

Because, it breaks LSP (mentioned in another answer). What that means here (just an example) is, I can always do like

Person x = new Spy();

and pass it to some other method, which might be like

void RegisterForNextBallGame(Person p)
{
playerList.Add(p.Name);
}

This method being unaware of the some spy roaming around the stadium, crashes while doing a simple honest duty!

Edit

Just to make it clear, this name=********** is still not a right solution. It will just save from the exceptions! Later, one might find lot of Persons walking down the code with name ********** which will cause later surprises and other issues.

A better solution would be a better design. Check Nathan's answer to get some hint.

C# - Can publicly inherited methods be hidden (e.g. made private to derived class)

It's not possible, why?

In C#, it is forced upon you that if you inherit public methods, you must make them public. Otherwise they expect you not to derive from the class in the first place.

Instead of using the is-a relationship, you would have to use the has-a relationship.

The language designers don't allow this on purpose so that you use inheritance more properly.

For example one might accidentally confuse a class Car to derive from a class Engine to get it's functionality. But an Engine is functionality that is used by the car. So you would want to use the has-a relationship. The user of the Car does not want to have access to the interface of the Engine. And the Car itself should not confuse the Engine's methods with it's own. Nor Car's future derivations.

So they don't allow it to protect you from bad inheritance hierarchies.

What should you do instead?

Instead you should implement interfaces. This leaves you free to have functionality using the has-a relationship.

Other languages:

In C++ you simply specify a modifier before the base class of private, public or protected. This makes all members of the base that were public to that specified access level. It seems silly to me that you can't do the same in C#.

The restructured code:

interface I
{
void C();
}

class BaseClass
{
public void A() { MessageBox.Show("A"); }
public void B() { MessageBox.Show("B"); }
}

class Derived : I
{
public void C()
{
b.A();
b.B();
}

private BaseClass b;
}

I understand the names of the above classes are a little moot :)

Other suggestions:

Others have suggested to make A() and B() public and throw exceptions. But this doesn't make a friendly class for people to use and it doesn't really make sense.



Related Topics



Leave a reply



Submit