C# 克服反向构造函数顺序的设计模式?
我有以下问题: 基类希望接收一些数据,但数据是由派生类构造函数初始化的,在C#中,派生类构造函数是在调用基类构造函数之后调用的 上下文/我试图解决的问题: 让我们调用基类C# 克服反向构造函数顺序的设计模式?,c#,design-patterns,constructor,C#,Design Patterns,Constructor,我有以下问题: 基类希望接收一些数据,但数据是由派生类构造函数初始化的,在C#中,派生类构造函数是在调用基类构造函数之后调用的 上下文/我试图解决的问题: 让我们调用基类Track,它的作用是构建一个表示视频游戏轨迹的网格 派生类(例如,Track1每个类都从特定的文件格式获取轨迹数据,它们之间的显著差异禁止在基类track中实现整个代码 Track的主要工作是抽象从派生类传入的数据,为此,它有派生类必须实现的抽象成员,例如int-GetVertexCount,Vector3-GetVertex
Track
,它的作用是构建一个表示视频游戏轨迹的网格
派生类(例如,Track1
每个类都从特定的文件格式获取轨迹数据,它们之间的显著差异禁止在基类track
中实现整个代码
Track
的主要工作是抽象从派生类传入的数据,为此,它有派生类必须实现的抽象成员,例如int-GetVertexCount
,Vector3-GetVertex(int)
更多地考虑它是一个ipacture
接口,可以从不同格式加载,例如BMP、JPEG,并将整个内容作为抽象返回
我面临的问题是:
在C#中,基类构造函数在派生类构造函数之前被调用,但我必须初始化派生类构造函数中的某些内容,然后我必须传递给基类构造函数。当我在上面的时候,我希望成员是不可变的,即只读的
问题:
如何首先在派生类构造函数中运行一些代码,以便将结果传递给基构造函数
回答:
下面的@Kit回答如下:我最终做了些什么,一切都很好:
具有讽刺意味的是,它最终成为了一个类似于C的API:)没有一种真正优雅的方式来完全满足您的要求,但我怀疑这是否真的必要。在构造函数中看到逻辑通常是一种代码味道 您还可以采取许多其他方法,比如使用静态
Create()
方法
class Derived : Base
{
private readonly object _o;
private Derived(object o, string s) : base(s)
{
_o = o;
}
public static Derived Create(string path)
{
var o = new object();// initialize from path
var s = o.ToString(); // get s from o.
return new Derived(o, s)
}
}
您也可以考虑使用继承来继承:
class Base
{
private readonly string _s;
public Base(string s)
{
_s = s.ToLower();
}
}
class Derived
{
private readonly object _o;
private readonly Base _b;
public Derived(string path)
{
_o = new object();// initialize from path
_b = new Base(_o.ToString());
}
}
但是,如果不知道您的实际目标和约束条件是什么,就很难知道这些方法中的哪一种可能是合适的。您已经告诉我们要如何解决问题,而不是要解决什么问题。假设不需要派生类的实例来执行所需的逻辑,您可以在调用基构造函数之前从派生构造函数调用静态方法 这里有一个简单的例子
public class Base
{
protected Base(SomeType data)
{
// base logic using data
}
}
public class DerivedOne : Base
{
public DerivedOne(int some, string data) : base(DerivedLogic(some, data))
{
...
}
private static SomeType DerivedLogic(int some, string data) => ...
}
public class DerivedTwo : Base
{
public DerivedTwo (string moreStuff) : base(DerivedLogic(moreStuff))
{
...
}
private static SomeType DerivedLogic(string moreStuff) => ...
}
这将按以下顺序运行:
DerivedLogic
public class Base
{
protected Base(SomeOtherType dataWrapper)
{
var data = dataWrapper.DerivedLogic();
// base logic using data
}
}
public class DerivedOne : Base
{
public DerivedOne(SomeOtherType otherType) : base(otherType)
{
...
}
}
或者在调用任何构造函数之前,在某处计算SomeType
,然后将其传入。这两种方法中的任何一种都是更好的设计,因为它如下所示:
您可以在
Base
类中创建abstract
或virtual
方法,并在\u s=s.ToLower()
之前邀请它,然后在Derived
中重写该方法。抱歉,我不够清楚,更新了我的问题,虽然您的方法确实很有趣,但我无法从该方法初始化只读
字段。为什么您需要从ctor处理\u o
,只需将处理移到该方法中,并将其作为返回值返回,并在基
中使用……听起来像是一个错误。你到底想做什么?这些类不应该彼此共享层次结构。加载轨道的东西本身不是轨道。它应该生成一个轨迹,而不是加载的轨迹。只是更新了我的问题以详细解释问题。谢谢,我最终得出以下结论:protected track(ITrackBuilder)
,然后我在派生类中插入了一个适当类型的新实例。因此,基本上,我将以一堆构建器结束,但作为回报,派生的轨迹只是没有任何代码的代理。