0

I currently have the following code pattern, where I am initialising a particular object of type MyThing in the constructor of the general class MyClass. However, in some specific derived class examples (e.g. MySpecialClass), I want to use a derived version of MyThing, which I have called MySpecialThing.

public class MyClass
{
    public MyClass()
    {
        this.MyThing = new MyThing();
    }

    public MyThing MyThing { get; set; }
}

public class MySpecialClass : MyClass
{
    public MySpecialClass()
    {
        this.MyThing = new MySpecialThing();
    }
}

My question is whether this is bad practice because in effect the MyThing property is being initialised twice, once in the base class and once in the derived class. Obviously I could pass in a boolean to the base class constructor or something to tell it not to bother initialising MyThing, but that might be overkill...

3 Answers 3

5

It depends how much overhead there is for creating MyThing.

However, there is a solution:

You can add a protected base class constructor which accepts a parameter of type MyThing, and initialise it there.

public class MyClass
{
    private readonly MyThing myThing;

    public MyClass(): this(new MyThing())
    {
    }

    protected MyClass(MyThing thing)
    {
        Contract.Requires(thing != null);
        myThing = thing;
    }

    public MyThing MyThing { get { return myThing; } }
}

public class MySpecialClass : MyClass
{
    public MySpecialClass(): base(new MySpecialThing())
    {
    }
}

I think this is a better approach than adding a bool to a public base class constructor.

I also think this is worth doing even if there is very little overhead to constructing a MyThing, because it much more clearly expresses the design.

I've also changed the design slightly to make myThing a readonly field, to express the intent that it should only be set at construction time. (If that's not the case and you want it settable later on, you will have to revert to a public property setter.)

Sign up to request clarification or add additional context in comments.

4 Comments

You can even delegate the default constructor in base class: public MyClass() : this(new MyThing()){}, but that's just a matter of opinion :) Overall, +1.
Great answer, thanks. Good idea about making it readonly as well. I am usually a fan of readonly variables, it's just annoying that there is no shorthand similar to the { get; set; } notation that expresses a readonly property and field.
I actually did add a request for "readonly" properties to Microsoft Connect a few years back, but it turned out there were some syntactic and other issues which made it less straightforward to implement than I expected. :)
Yes, I suppose as things stand the only way to get the values in would be via the constructor, and it's hard to define an "implicit" syntax for that. They could instead allow the object initialiser syntax to be used on constructors for readonly variables, don't know if that would open up other cans of worms.
1

Are you concerned with performance or maintainability?

The performance issue would only make sense if MyThing constructor is expensive, or you have to create a lot of objects in tight loop.

I would be more worried about maintainability as you have multiple places where the object state is initialized. You could pass it to a protected base class constructor from derived class, and have a default constructor which uses MyThing by default

Comments

0

Use protected:

class BaseClass
{
    protected SomeType MyThing;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.