简体   繁体   English

强制子类初始化变量

[英]Force a child class to initialize a variable

I have a class Foo that has a field _customObject that must be initialized. 我有一个类Foo ,它有一个必须初始化的字段_customObject I also have a class Bar that inherits from Foo : 我还有一个继承自Foo的类Bar

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: 我无法在Foo初始化对象_customObject ,因为每个继承的子CustomObject都包含一个不同的CustomObjectCustomObject ,因此必须在每个子类中初始化它:

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. 其他人将实现从Foo继承的新类,所以我想知道是否有一种方法可以显示构建时间中的错误,类似于未实现抽象方法时。 If CustomObject is not initialized, a NullReferenceException will be thrown due to the use of the _customObject variable, ending in an application crash. 如果未初始化CustomObject ,则会因为使用_customObject变量而抛出NullReferenceException ,从而导致应用程序崩溃。

You can add a parameter to your Foo constructor: 您可以向Foo构造函数添加参数:

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: 然后,您的派生类将被强制调用它,传入CustomObject或从中派生的东西:

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. 这并不完全保护你,因为有人仍然可以将null传递给基础构造函数,但至少他们会解释为什么他们在运行时获得NullReferenceError

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. “James Thorpe”提供的答案是正确的(我已经提出了它),但我想在这里分享另一个选项:你可以将你的类标记为抽象,并引入一个抽象属性而不是“_customObject”字段。 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. 此外,使用第一个解决方案,可以在构造函数中验证传入的值 - 但是,这将是运行时验证。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM