首先调用基类的构造函数

时间:2014-04-12 12:56:53

标签: c#

如果得到这样的话:

public abstract class BaseFoo
{
    public BaseFoo()
    {
        FooMethod();
    }

    public abstract void FooMethod();
}

public class Foo : BaseFoo
{
    private Stream _stream;

    public Foo(Stream stream)
    {
        _stream = stream;
    }

    public override void FooMethod()
    {
        //do anything with the stream
        _stream.Read(...);

        //--> _stream = null
    }
}

如你所见。有一个大问题。 BaseFoo类的ctor调用抽象方法FooMethod。在其实现中,它尝试访问_stream字段。但是_stream为null因为执行了Foo类的ctor。

是否有任何可能性或模式来解决这种情况(我能够改为基类)。我只是在寻找一个很好的解决方案。

有没有可能做那样的事情?

public Foo(Stream stream)
{
    _stream = stream;

    base();
}

如果有人有想法会很好。

2 个答案:

答案 0 :(得分:2)

Calling overridable methods from constructors is discouraged正是出于问题中列出的原因。

构造完成后调用FooMethod方法。

答案 1 :(得分:0)

在初始化继承的类时,您还需要首先初始化其基类。如果你改变构造函数以接受一些参数(即删除默认构造函数),你将能够很容易地看到它:

public abstract class BaseFoo
{
    public BaseFoo(bool testToDoSomething)
    {
        FooMethod();
    }

    public abstract void FooMethod();
}

在这种情况下,代码不会编译,因为Foo类会说BaseFoo不包含您需要调用的无参数构造函数。除此之外,这不是无参数构造函数的目的。

我可以想到一个解决方法,但它并不太好,你可能想以不同的方式做到这一点。但如果你真的没有,你可以这样做:

public abstract class BaseFoo
{
    private Action toRunOnConstruct;
    public BaseFoo(Action toRunOnConstruct)
    {
        this.toRunOnConstruct = toRunOnConstruct;
        toRunOnConstruct.Invoke();
    }
}

public class Foo : BaseFoo
{
    private Stream _stream;

    public Foo(Stream stream) : base(()=> SomethingToDoWithTheStream(stream))
    {
        _stream = stream;
    }

    public static void SomethingToDoWithTheStream(Stream stream)
    {
        //do anything with the stream
        stream.Read(...);

        //--> _stream = null
    }