只是想澄清一下我对XmlWriter和抽象类的工作原理的理解。
我的想法是,虽然它可以包含可以由继承类使用的基本方法,但是无法实例化抽象类。
因此,在研究XmlWriter时,我发现要实例化XmlWriter,你调用XmlWriter.Create(....,它返回一个...... XmlWriter的实例,然后可以使用它:
FileStream fs = new FileStream("XML.xml", FileMode.Create);
XmlWriter w = XmlWriter.Create(fs);
XmlSerializer xmlSlr = new XmlSerializer(typeof(TestClass));
xmlSlr.Serialize(fs, tsIn);
经过测试,这显然有效。任何人都可以帮助我了解这里发生了什么。据我所知,这里有或者应该没有“实例”吗?
答案 0 :(得分:9)
您无法使用new
创建实例,但此处使用的Create
是所谓的静态工厂方法;它不是构造函数。事实上,Create
返回的对象不属于abstract class XmlWriter
,而是属于其他一些具体的子类。
答案 1 :(得分:4)
你得到的对象没有任何抽象概念。 .NET框架中有13个类来实现XmlWriter。它们都是内部的,如果您使用Reflector查看源代码,则只能看到它们的名称。
不必亲自了解这13个课程的名称对您和Microsoft都非常有价值。对你而言,因为你不必学习选择正确的细节。对Microsoft来说,因为他们可以完全改变那些类的实现,甚至名称,你的代码也不会注意到。
这称为Factory Pattern。
答案 2 :(得分:1)
这就是所谓的factory pattern。
在这种情况下,抽象类还充当负责创建扩展自身的类的具体实例的工厂。
通过这种方式,创建正确类的责任被移交给工厂,工厂通常会根据您传入的某些参数或其他内容(如config / environment等)来决定要创建的类。< / p>
答案 3 :(得分:0)
感谢。一旦我对返回的对象的类型进行了测试,我得到了一个派生自XmlWriter的类型。令我困惑的是,我没想到抽象基类能够引用它自己的子类。
.NET必须根据输入参数确定要返回的具体XmlWriter的类型。
XmlWriter似乎(对我而言)比我在阅读此处的所有评论后看到的其他实现更不直观。例如以下链接中的示例使用具体类中的Create方法。
http://www.codeproject.com/KB/architecture/CSharpClassFactory.aspx
我在这里删掉了一些代码,以证明我自己可以通过抽象类上的Create方法实现功能。抽象类的create方法确实可以引用派生类型,如下所示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestFactoryPattern
{
public abstract class Input
{
public int Val;
}
public class InputObjA : Input
{
public InputObjA()
{
Val = 1;
}
}
public class InputObjB : Input
{
public InputObjB()
{
Val = 2;
}
}
public abstract class MyXmlWriter
{
public static int InputVal;
public static MyXmlWriter Create(Input input)
{
InputVal = input.Val;
if (input is InputObjA)
{
return new MyObjAXmlWriter();
}
else if (input is InputObjB)
{
return new MyObjBXmlWriter();
}
else
{
return new MyObjAXmlWriter();
}
}
public abstract void WriteMyXml();
}
public class MyObjAXmlWriter : MyXmlWriter
{
public override void WriteMyXml()
{
Console.WriteLine("Input A Written: " + InputVal);
}
}
public class MyObjBXmlWriter : MyXmlWriter
{
public override void WriteMyXml()
{
Console.WriteLine("Input B Written: " + InputVal);
}
}
public class Program
{
public static void Main()
{
InputObjA a = new InputObjA();
MyXmlWriter myXml1 = MyXmlWriter.Create(a);
myXml1.WriteMyXml();
InputObjB b = new InputObjB();
MyXmlWriter myXml2 = MyXmlWriter.Create(b);
myXml2.WriteMyXml();
}
}
}
感谢大家的答案和意见。