C#'static abstract'方法替代实例化子类
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#'static abstract'方法替代实例化子类相关的知识,希望对你有一定的参考价值。
我知道我所要求的不会以这种方式工作,但我认为我最初的想法并不是那么愚蠢。
所以,想象一下像这样的代码结构:
abstract class Element
class A : Element
class B : Element
class C : Element
Element父类正在处理文件加载并将子类保存到XML文件之类的数据结构。
为了保存所有Elements,Element类创建基本的XML结构,并将XmlElement传递给每个子类的'OnSave()'方法。每个子节点的数据结构略有不同,因此它们实现了如何在父节点传递它们的XmlElement下保存自己。
但是,要加载,父类应遍历给定的XML文件,并根据文件中包含的信息实例化子对象。由于保存系统配置为在相应类型的分支下存储所有子实例,因此它知道要为每个数据集实例化哪种类型。因为所有子对象的文件结构再次略有不同,所以让子实现一个静态函数是明智的,该函数创建一个自己的实例,其中填充了父代传递给所述函数的数据。因为我要求所有孩子都实现这个功能,我本能地开始打字
protected static abstract Element Load(XmlElement xml);
直到我注意到这没有意义。
我现在的问题是:这样的系统如何以智能方式实现?
编辑:请注意,Element的Load函数是静态的。
在基于类的编程中,工厂方法模式是一种创建模式,它使用工厂方法来处理创建对象的问题,而无需指定将要创建的对象的确切类。这是通过调用工厂方法创建对象来完成的 - 在接口中指定并由子类实现,或者在基类中实现并可选地由派生类覆盖 - 而不是通过调用构造函数。
基本思想是将您的create(实例化您派生类的逻辑)移动到单独的类/方法。
当您引入新的派生类时,您只需要实现新的派生类并更新工厂方法。
扩展您的示例:
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'方法替代实例化子类的主要内容,如果未能解决你的问题,请参考以下文章
abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?
部分关键字--this/extends/super/static/final/abstract/访问权限总结
abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?