强制子类初始化变量

Ign*_*cio 7 .net c# inheritance

我有一个必须初始化Foo的字段的类_customObject.我还有一个Bar继承自的类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
}
Run Code Online (Sandbox Code Playgroud)

我无法初始化该对象_customObject,Foo因为每个继承的子节点都包含一个不同的子节点CustomObject,因此必须在每个子类中初始化它:

public class Bar : Foo
{
    public Bar()
    {
        _customObject = new CustomObjectInherited1();
    }
}


public class Baz : Foo
{
    public Baz()
    {
        _customObject = new CustomObjectInherited2();
    }
}
Run Code Online (Sandbox Code Playgroud)

其他人将实现继承的新类Foo,所以我想知道是否有一种方法可以显示构建时间中的错误,类似于未实现抽象方法时.如果CustomObject未初始化,NullReferenceException则由于使用_customObject变量而将抛出 a ,以应用程序崩溃结束.

Jam*_*rpe 8

您可以向Foo构造函数添加参数:

public abstract class Foo
{
    protected CustomObject _customObject;

    public Foo(CustomObject obj)
    {
        // Do stuff
        _customObject = obj;
    }
    // Other methods that use _customObject
}
Run Code Online (Sandbox Code Playgroud)

然后,您的派生类将被强制调用它,传入一个CustomObject或从它派生的东西:

public class Bar : Foo
{
    public Bar():base(new CustomObjectInherited1())
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

不调用基础构造函数将导致编译时错误.这并不完全保护你,因为有人仍然可以传递null给基础构造函数,但至少他们会解释为什么他们NullReferenceError在运行时获得它.


Jür*_*ock 5

您可以通过创建一个需要子类覆盖它的抽象方法来强制使用它。

public abstract class Foo
{
    protected abstract CustomObject CreateCustomObject();
}

public class Bar : Foo
{
    protected override CustomObject CreateCustomObject()
    {
        return new BarCustomObject();
    }
} 
Run Code Online (Sandbox Code Playgroud)

或我最喜欢的解决方案:通过通用约束来强制实施。

public abstract class Foo<T> : where T : CustomObject, new()
{
    protected T _customObject;
    public Foo()
    {
        this.CustomObject = new T();
    }
}

public class Bar : Foo<BarCustomObject>
{
}
Run Code Online (Sandbox Code Playgroud)