1

I'm trying to make a class inherited from another class that I don't have access to.

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

The Text and Visible properties are still available when calling like this:

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

Is there a way to make these two last statements invalid?

LuizLoyola
  • 386
  • 3
  • 20
  • 1
    Possible duplicate of [How to hide an inherited property in a class without modifying the inherited class (base class)?](https://stackoverflow.com/questions/1875401/how-to-hide-an-inherited-property-in-a-class-without-modifying-the-inherited-cla) – Hasan Fathi Feb 07 '18 at 20:18

2 Answers2

4

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;
    }
}
npearson
  • 692
  • 4
  • 17
  • I was also trying "new". But I am surprised why "new private string Text" is still allowed?? I mean not as property.... just declared as variable.... But the private is not effective there.... – Pavan Chandaka Feb 07 '18 at 20:04
  • To my knowledge, if you change the access modifier, you won't hide the inherited property. Oh I see what you mean...just the fact that it is allowed. – npearson Feb 07 '18 at 20:06
  • 1
    Not saying this is wrong, but keep in mind there are some subtle "gotchas" when using `new`: https://stackoverflow.com/a/1399151/68432. Namely "_Any code that is not referencing your class but the parent class will use the parent class implementation._" – Paul Suart Feb 07 '18 at 20:07
  • @npearson I see that, But compiler should respect local private variables first rt.... :) :)..... But I see that values can not be assigned to objects.... It just says Null, even though some value is assigned – Pavan Chandaka Feb 07 '18 at 20:08
2

Inheritance is inheritance. If your parents passed you the trait for blue eyes, the trait is in your genetic code. That doesn't mean you have blue eyes, though. While you inherit the trait, you might have brown eyes (dominant trait) and therefore you express that trait instead.

Code works similarly. If foo inherits from bar, every foo will have the traits of a bar. What you can do, however, is override the traits with traits unique to the class.

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

Now that I've show you how, don't do it if you can avoid it. If you're worried about inheriting a complex object like a Label and you don't want to expose some of what it inherits, your problem probably has nothing to do with with the modifiers on the properties, and everything to do with the scope modifier on your actual instance. You'd be better off using the object in a more narrow scope, then letting it fall out of scope before anything else would access it.

The reason you want to avoid this is code smell. Lets say you make a class library that uses your MyLabel. Because it inherits from Label, I know I can use it just like a label. Then, when I do this:

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

...I will then proceed to spend an hour trying to find out why myLanta's text is always "Nope!" This is why it's important to throw an exception here, or at least use a summary so when another person is coding, they can see at a glance that no matter what they assign for "Text", it will always be "Nope".

My recommendation is that if you need to narrow the available properties of a class, make the class a component of a new class instead of inheriting it.

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
}

Then, if you want to return properties of the Label, you can with methods and properties you control without having to worry about inheritance issues. If you don't provide an accessing method to the Label's property, that property never sees the light of day and is effectively private to the class. This also prevents broken code from someone passing your MyLabel in place of a Forms.Label because that inheritance contract will not exist.

CDove
  • 1,940
  • 10
  • 19
  • This is a good answer, but I would need to replicate every single property I want to use outside. So this doesn't work for me. But nice answer! Sure it will be useful for another programmer. – LuizLoyola Feb 07 '18 at 20:39