I have a class Foo that has a field _customObject that must be initialized. I also have a class Bar that inherits from Foo:
public abstract class Foo
{
    protected CustomObject _customObject;
    public Foo()
    {
        // Do stuff
    }
    // Other methods that use _customObject
}
public class Bar : Foo
{
    // Constructor and other methods
}
I can not initialize the object _customObject in Foo because every child inherited contains a different child of CustomObject, so it must be initialized in every child class:
public class Bar : Foo
{
    public Bar()
    {
        _customObject = new CustomObjectInherited1();
    }
}
public class Baz : Foo
{
    public Baz()
    {
        _customObject = new CustomObjectInherited2();
    }
}
Other people are going to implement new classes that inherit from Foo, so I was wondering if there is a way that an error in build time is shown, similar to when an abstract method is not implemented. If CustomObject is not initialized, a NullReferenceException will be thrown due to the use of the  _customObject variable, ending in an application crash.
You can add a parameter to your Foo constructor:
public abstract class Foo
{
    protected CustomObject _customObject;
    public Foo(CustomObject obj)
    {
        // Do stuff
        _customObject = obj;
    }
    // Other methods that use _customObject
}
Your derived classes will then be forced to call it, passing in a CustomObject, or something derived from it:
public class Bar : Foo
{
    public Bar():base(new CustomObjectInherited1())
    {
    }
}
Not calling the base constructor will result in a compile time error.  This doesn't entirely protect you, as someone could still pass null to the base constructor, but at least they'll have an explanation as to why they're getting a NullReferenceError at runtime.
You can force it by creating a abstract method which requires child classes to override it.
public abstract class Foo
{
    protected abstract CustomObject CreateCustomObject();
}
public class Bar : Foo
{
    protected override CustomObject CreateCustomObject()
    {
        return new BarCustomObject();
    }
} 
Or my favorite solution: Enforce it by generic constraints.
public abstract class Foo<T> : where T : CustomObject, new()
{
    protected T _customObject;
    public Foo()
    {
        this.CustomObject = new T();
    }
}
public class Bar : Foo<BarCustomObject>
{
}
                        The answer provided by "James Thorpe" is correct (I've upvoted it already), but I wanted to share just another option here: You could mark your class as abstract and introduce an abstract property instead of the "_customObject" field. That way, at least the first initializer will be forced to implement it. The downside is that you'll loose the enforcement on subsequent level subclasses:
public abstract class Foo
{
    protected abstract CustomObject CustomObject {get; }
    public Foo()
    {
        // Do stuff
    }
    // Other methods that use _customObject
}
public class Bar : Foo
{
    // Constructor and other methods
    protected override CustomObject CustomObject
    {
        get { return "X"; }
    }
}
Also, with the first solution it's possible to validate the passed in value in the constructor - though, that'll be a runtime validation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With