Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 解决构造函数中的虚拟成员调用_C#_.net_Oop_Resharper - Fatal编程技术网

C# 解决构造函数中的虚拟成员调用

C# 解决构造函数中的虚拟成员调用,c#,.net,oop,resharper,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 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
    }
}
公共抽象类ExampleBase:IExampleBase
{
受保护的ExampleBase()
{
这是SetupData();
}
受保护的抽象词典相关数据{get;set;}
受保护的抽象数据();
public void ProcessData()
{
//使用相关数据
}
}
和派生类:

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

    protected override void SetupData()
    {
        this.RelevantData = new Dictionary<int, Adress>
        { 1, new Adress { ... } },
        { 2, new Adress { ... } }
    }
}
公共类示例:ExampleBase
{
公共示例()
{
}
受保护的覆盖无效设置数据()
{
this.RelevantData=新词典
{1,新地址{…},
{2,新地址{…}
}
}
在基类中,ReSharper告诉我

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

我理解由于执行顺序的原因调用该方法是危险的。。但我如何解决这个问题呢

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

派生类:

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

    protected override void SetupData()
    {
        this.RelevantData = new Dictionary<int, Adress>
        { 1, new Adress { ... } },
        { 2, new Adress { ... } }
    }
}
  • 设置数据
基类:

  • 处理数据

调用Example(以及其他所有派生类)的构造函数中的SetupData而不是ExampleBase,并将Example设置为密封类


问题是SetupData可能访问一些将由示例构造函数初始化的内容。但是示例构造函数只有在ExampleBase构造函数完成后才被调用。

您的基类构造函数首先被调用。如果子类中的重写方法依赖于其构造函数中所做的任何事情,那么它将不起作用。就我个人而言,我会寻找一种不同的设计,可能是将抽象类传递到派生类中,而不是使用继承。你接受这一事实是危险的,并(试图)防止这种情况发生。这是一个设计缺陷

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


如果不可能的话。使用注释或任何其他可用方法明确说明,开发人员在更新代码时应考虑此问题。

因此每个派生类中都有几行代码
如果需要控制流程顺序,则可以执行此操作

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();
    }
} 

那么
SetupData
是什么意思?为什么必须在
ExampleBase
构造函数中而不是在派生类构造函数中执行此操作?这里没有足够的上下文。SetupData()设置了一些数据(取决于派生类),以便在基类中进一步使用。我想在基类构造函数中调用它,这样我就不必在它在基类构造函数中使用的每个派生类中调用它了?为什么每个派生类构造函数不能只做它需要的任何设置呢?我认为这可以解决问题。。我只是试着在基类中这样做,因为它在每个派生类中都是一样的,但我认为你是对的。因此,如果我理解正确:在每个派生类的构造函数中调用SetupData(),并将这些派生类密封起来?您不必密封该类。。。只要让每个类做自己的设置,不管它需要什么。某些派生类可能不需要任何数据设置。(例如,我会杀死抽象成员。)但是,基类构造函数是否需要访问这些元素?我们仍然没有足够的背景…我认为这不能解决问题。因为示例可以是另一个类的“基”,除非您密封它。