gpt4 book ai didi

C# 'static abstract' 实例化子类的替代方法

转载 作者:行者123 更新时间:2023-11-30 16:40:54 28 4
gpt4 key购买 nike

我知道我的要求不会以这种方式起作用,但我认为我最初的想法并不那么愚蠢。

所以,想象一下这样的代码结构:

abstract class Element
class A : Element
class B : Element
class C : Element

Element 父类处理文件加载并将子类保存到数据结构(如 XML 文件)中。

为了保存所有元素,Element 类创建基本的 XML 结构并将 XmlElement 传递给每个子类的“OnSave()”方法。每个 child 的数据结构都略有不同,因此他们正在实现如何将自己保存在 parent 传递给他们的 XmlElement 下。

然而,要加载,父类应遍历给定的 XML 文件并根据文件中包含的信息实例化子对象。因为保存系统被配置为将所有子实例存储在相应类型的分支下,所以它知道为每个数据集实例化哪种类型。因为所有子对象的文件结构再次略有不同,所以让子对象实现一个静态函数会很聪明,该函数创建一个自身的实例,其中填充父对象传递给所述函数的数据。因为我会要求所有 child 实现这个功能,所以我本能地开始打字

protected static abstract Element Load(XmlElement xml);

直到我发现这没有意义。

我现在的问题是:如何以巧妙的方式实现这样的系统?

编辑:请注意,Element 的 Load 函数将是静态的。

最佳答案

您可以使用 Factory Method/Pattern

In class-based programming, the factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created. This is done by creating objects by calling a factory method—either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes—rather than by calling a constructor.

基本思想是将您的创建(派生类的实例化逻辑)移动到单独的类/方法。

当你引入一个新的派生类时,你只需要实现你的新派生类并更新你的工厂方法。

扩展你的例子:

public abstract class Element
{
public abstract void Load(XmlElement xml);
}

public sealed class ClassA
: Element
{
public override void Load(
XmlElement xml)
{
throw new NotImplementedException();
}
}

public sealed class ClassB
: Element
{

public override void Load(
XmlElement xml)
{
throw new NotImplementedException();
}
}

public sealed class ClassC
: Element
{
public override void Load(
XmlElement xml)
{
throw new NotImplementedException();
}
}

工厂:

public static class ElementFactory
{
public static Element Create(
XmlElement element)
{
if (element.Value == "1")
{
return new ClassA();
}
else if (element.Value == "2")
{
return new ClassB();
}
else if (element.Value == "3")
{
return new ClassB();
}

throw new Exception("Could not determine element class");
}
}

用法:

XmlDocument xmlDoc = new XmlDocument();
var xmlElement = xmlDoc.CreateElement("element1");

var element = ElementFactory.Create(xmlElement);

element.Load(xmlElement);

也可以去掉load方法,使用每个派生类的构造函数:

public abstract class Element
{
public Element(
XmlElement xml)
{
}
}

public sealed class ClassA
: Element
{
public ClassA(XmlElement xml) : base(xml)
{
}
}

public sealed class ClassB
: Element
{
public ClassB(XmlElement xml) : base(xml)
{
}
}

public sealed class ClassC
: Element
{
public ClassC(XmlElement xml) : base(xml)
{
}
}

更新工厂:

那么你的调用代码就变得更简单了:

public static Element Create(
XmlElement element)
{
if (element.Value == "1")
{
return new ClassA(element);
}
else if (element.Value == "2")
{
return new ClassB(element);
}
else if (element.Value == "3")
{
return new ClassB(element);
}

throw new Exception("Could not determine element class");
}

更新的用法:

XmlDocument xmlDoc = new XmlDocument();
var xmlElement = xmlDoc.CreateElement("element1");

var element = ElementFactory.Create(xmlElement);

关于C# 'static abstract' 实例化子类的替代方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50210281/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com