Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Best way to replace an abstract class property callable from parent in C#

In a lot of languages, you can override the value of a property of a class when extending an abstract class, and the parent methods will read this new variable when used, an example would be something like this:

abstract class A {
    protected string foo;
    
    void PrintFoo() {
        print(foo);
    }
}

class B extends A {
    protected string foo = "bar";
}

(new B()).PrintFoo(); // outputs: bar

In C# I haven’t been able to find a standard way to do this, as this is not allowed.

One way I’ve found is by passing it by parent constructor like:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

abstract class A {
    protected string foo;
    public A(string foo) {
        this.foo = foo;
    }

    void PrintFoo() {
        Console.WriteLine(foo);
    }
}

class B : A {
    public B() : A("bar") {}
}

(new B()).PrintFoo(); // outputs: bar

But clearly this is not clean at all.
Another way I’ve seen is by making a virtual string and overriding it later (which would be similar to the other languages):

abstract class A {
    protected virtual string Foo { get; }

    void PrintFoo() {
        Console.WriteLine(Foo);
    }
}

class B : A {
    protected override string Foo {
        get { return "bar"; }
    }
}

(new B()).PrintFoo(); // outputs: bar

It seems as to me the second way is the appropriate one, but it’s not as clean as I expected.

Is there a better way?

>Solution :

You can’t override a field, only methods (and properties and the like). In order to change a fields default-value, you can assign it in the derived class’ constructor:

class B : A
{
    public B() { foo = "bar"; } // you have access to foo, as it's protected field
}

You should however make your field readonly, to avoid changing it after your instance was created.

Apart from this what you consider "not clean at all" is a really good solution, in my opinion, as it enables you to limit the access to the field even further to private:

class A
{
    private string foo;
    public A(string f) { this.foo = f; }
}
class B : A
{
    public B : A("bar") { }
}

This way not even B can access or manipulate the fields value. However it’s pretty up to you if you need this kind of security.

Another way would be to wrap the field in a property and override that one:

class A
{
    public virtual string Foo => null;
}
class B : A
{
    public override string Foo => "bar";
}

I’d not say this is per-se better, as properties aren’t per-se better than fields. If it were that simple, public or prtoteced fields probably were forbidden by the compiler (shouldn’t be that hard to implement that). However exposing fields to the outside of your class makes it hard to keep track on when they change. That’s whay people love properties, as they encapsulate the field to keep track on its changes. It’s easy to validate the new value for a property. Doing that on a field can become a nighmare soon.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading