Advanced base constructor calls in C#

by Marcel Veldhuizen 5. September 2013 14:00

Note: This article was edited after a Gonçalo Lopes presented me with a better solution. Thanks!

Every now and then you run into a situation where you wish your programming language of choice was just a tad more flexible than it actually is. For example, constructors in C# always have to directly call one of the base type constructors as the first thing they do (or do they? keep reading).

Yesterday I ran into a situation where I would like my derived class to always use the same implementation* for a certain injectable dependency. No problem:

public class FooBase
{
    public FooBase(IDependency dependency)    { /* stuff here */ }
}

public class MyFoo : FooBase
{
    public MyFoo() : base(new MyDependency()) { }
}

The dependency is created on the fly and my base class constructor is happy. However, my derived class also needed to make use of this dependency and my base class does not expose any property or field for me to access it. So before calling the base constructor, I would have liked to store a reference to this newly created MyDependency object.

If we switch to Java syntax for a moment, it would be something like this:

public class MyFoo
{
    private MyDependency _dependency;

    public MyFoo()
    {
        // Note that this is not actually valid in Java either.
        // The call to super must be the first statement in the constructor.
        _dependency = new MyDependency();
        super(myDependency);
    }
}

Now, the reason why this isn't allowed makes perfect sense. We'd be accessing a field of this type before the base constructor is initialized, but for technical reasons the compiler is enforcing initialization to occur from base type to more specialized types. Now, I'm not an expert at compiler creation, but I think this would have been perfectly fine to allow the use of local variables:

public MyFoo()
{
    MyDependency dependency = new MyDependency();
    super(myDependency);
    _dependency = dependency;
}

It even seems like a easy enough thing to let the compiler to automatically park the reference on the stack temporarily, but alas.

My original workaround

So far I've neglected to mention a lesser known feature of C#, which is to include a method call in the base constructor call:

public class MyFoo : FooBase
{
    public MyFoo() : base(CreateDependency())
    {
    }

    private static IDependency CreateDependency()
    {
         return new MyDependency();
    }
}

This code is essentially identical to the first code snippet. If you were paying attention, you noticed that the method I'm calling is static. This is again to prevent access to fields prior to initialization of the base type. So how does this help me? Well, originally I wrote something like this:

// =========================
// Warning: evil code inside
// =========================

public class MyFoo: FooBase
{
    private static IDependency _tempDependency;
    private readonly IDependency _dependency;

    public MyFoo() : base(CreateDependency())
    {
        _dependency = _tempDependency;
        _tempDependency = null;
        Monitor.Exit(typeof(MyFoo));
    }

    private static IDependency CreateDependency()
    {
        Monitor.Enter(typeof(MyFoo));
        _tempDependency = new MyDependency();
        return _tempDependency;
    }
}

The locks in here (Monitor.Enter and Monitor.Exit) are just in case you'd be mass creating these objects in multiple threads. Performance wouldn't be good, but at least it would be error free. Use of ThreadStaticAttribute would be another option.

A better solution

Using the code above seemed like a very bad idea. Luckily, there was a better solution to my presented problem, as Gonçalo Lopes pointed out after I posted the original article: Just use a private constructor to both create an object and put it on the stack:

public class MyFoo : FooBase
{
    public MyFoo() : this(new MyDependency()) { }

    public MyFoo(IDependency dependency) : base(dependency)
    {
        _dependency = dependency;
    }
}

Wrapping up

In the end, I didn't actually need any nasty workarounds, which I'm really glad about. Trying to solve the problem once again made me aware of this ability to call static methods before the base constructor however, which has plenty of other uses. You could do string manipulation, constructing complex object structures in a more readable fashion, code reuse, etc.

*: That doesn't sound very Liskov, does it? The reality is a bit different, but it is beside the point of this post.

Tags: ,

Programming | .NET

Comments (2) -

Gonçalo Lopes
1/10/2015 4:25:35 PM #

You gave the answer here:

public MyFoo()
{
    MyDependency dependency = new MyDependency();
    super(myDependency);
    _dependency = dependency;
}

but then for some reason used a much more complicated and error-prone solution. Why not simply do this?

public MyFoo()
   : this(new MyDependency())
{
}

private MyFoo(IDependency dependency)
   : base(dependency)
{
    _dependency = dependency;
}

In this way you have both dependencies accessible. Basically you create the temporarily "stack" variable you mentioned by adding another constructor overload (you can make it private so this doesn't bubble up to users of your class).

Reply

Marcel Veldhuizen
2/6/2015 11:38:17 PM #

You're completely right in that your method would solve the presented problem in a much cleaner way.
I can't recall the exact case that I was tempted to use my code on (it was slightly more complicated), but I think the private constructor would have solved that as well.

I feel silly for not thinking of this solution myself, so thanks for pointing it out to me Smile

Reply

Add comment

Marcel Veldhuizen

Software Architect by profession, mostly focused on Microsoft .NET technology.

Metal enthusiast; I love going to concerts :)

 

RecentPosts

Recent Tweets

Note: For Customization and Configuration, CheckOut Recent Tweets Documentation