关于C#:使用附加方法的构造函数中的虚拟调用

Virtual call in constructor with additional method

本问题已经有最佳答案,请猛点这里访问。

我有一个问题,我需要在抽象类的构造函数中调用一个虚拟函数。

1
2
3
4
5
6
7
8
9
10
internal abstract class Item
{
    protected Item(...)
    {
        ...
        CreateBuyButton(...);
    }

    protected abstract void CreateBuyButton(...);
}

如果我有类似这样的代码,resharper会通知我这个问题,但是如果我将调用重构为另一个方法,resharper似乎不会将这视为问题,我也不确定这是否是问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
internal abstract class Item
{
     protected Item(...)
    {
        ...
        GetValue(...);
    }

    protected abstract void CreateBuyButton(...);

    private void GetValue(...)
    {
        CreateBuyButton(...);
    }
}

这个有效吗?问题还会继续吗?


是的,这可能还是个问题

当基类的构造函数运行时,派生类的构造函数尚未运行。如果重写的方法包含依赖于派生类的状态的逻辑,则可能会遇到问题,因为状态尚未初始化。

您可以通过从构造函数中移除逻辑并使用惰性初始化来避免该问题,例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
abstract class Item
{
    private Button _buyButton = null;

    public Item()
    {
        //Do nothing
    }

    public Button BuyButton
    {
        get
        {
            if (_buyButton == null) CreateBuyButton(); //Lazy initialization
            return _buyButton;
        }
    }

    public abstract void CreateBuyButton();
}

如果您需要通过某种状态,则必须存储它:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
abstract class Item
{
    private string _productName;
    private Button _buyButton = null;

    public Item(string productName)
    {
        _productName = productName;
    }

    public Button BuyButton
    {
        get
        {
            if (_buyButton == null) CreateBuyButton(_productName); //Lazy initialization
            return _buyButton;
        }
    }

    public abstract void CreateBuyButton(string caption);
}