如何使用XmlWriter.Create(...?)实例化抽象类XmlWriter?

时间:2010-05-21 11:08:28

标签: c# .net

只是想澄清一下我对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);

经过测试,这显然有效。任何人都可以帮助我了解这里发生了什么。据我所知,这里有或者应该没有“实例”吗?

4 个答案:

答案 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();

            }


  }
}

感谢大家的答案和意见。