在构造函数中解决虚拟成员调用

时间:2015-04-20 13:18:25

标签: c# .net oop resharper

我有一个抽象类:

public abstract class ExampleBase : IExampleBase
{
    protected ExampleBase() 
    {
        this.SetupData();
    }

    protected abstract Dictionary<int, Adress> RelevantData { get; set; }

    protected abstract void SetupData();

    public void ProcessData() 
    {
        // use RelevantData
    }
}

派生类:

public class Example : ExampleBase
{
    public Example()
    {
    }

    protected override void SetupData()
    {
        this.RelevantData = new Dictionary<int, Adress>
        { 1, new Adress { ... } },
        { 2, new Adress { ... } }
    }
}

在基类中,ReSharper告诉我

  

构造函数中的虚拟成员调用

我理解由于执行顺序而调用该方法很危险..但我该如何解决此问题?

上下文:我想在每个派生类中设置数据,然后在基类中处理。我想在基类中调用SetupData()方法,因为它在每个派生类中都是相同的。

派生类:

  • 设置数据

基类:

  • 处理数据

4 个答案:

答案 0 :(得分:14)

你没有。你接受这是危险的事实,并且(尽量)防止这种情况发生。这是一个设计缺陷!

例如,可以通过将调用移动到最高级别类,或者使每个类对其自己负责来阻止此操作,从而删除方法调用的不安全部分。然后,您不需要另一个类(基类)来负责其派生类。

如果那是不可能的。使用注释或任何其他可用的方法非常清楚,开发人员在更新代码时应考虑此问题。

答案 1 :(得分:0)

在Example(和其他所有派生类)的构造函数中调用SetupData而不是ExampleBase,并将Example作为密封类。

问题是SetupData可以访问将由Example构造函数初始化的内容。但是只有在ExampleBase构造函数完成后才调用Example构造函数。

答案 2 :(得分:0)

首先调用您的基类构造函数。如果子类中的override方法依赖于在其构造函数中完成的任何操作,那么它将无法工作。就个人而言,我会寻找一种不同的设计,可能会将抽象类传递给派生类而不是使用继承。

答案 3 :(得分:0)

所有派生类中都有几行代码 如果您需要控制流程订单,那么您可以执行此操作

public abstract class MyBase 
{
    public void ProcessData()
    {
        bool processData = true;
    }
    public MyBase()
    {
        bool myBase = true;
    }
    public MyBase(int pass)
    {
        bool myBase = true;
    }
}
public class Example : MyBase
{
    public void GetData() {}
    public Example()
        : base(1)
    {
        bool example = true;
        GetData();
        ProcessData();
    }
}