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


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

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


3810
2018-05-21 11:08


起源



答案:


您无法使用创建实例 new但是 Create 因为它在这里使用的是所谓的静态工厂方法;它不是构造函数。实际上,你会发现返回的对象 Create 不属于 abstract class XmlWriter,但一些其他具体的子类。

也可以看看


9
2018-05-21 11:11





你得到的对象没有任何抽象概念。 .NET框架中有13个类来实现XmlWriter。它们都是内部的,如果你用Reflector查看源代码,你只能看到它们的名字。

不必亲自了解这13个类的名称对您和Microsoft都非常有价值。对你而言,因为你不必学习选择正确的细节。对微软来说,因为他们可以完全改变那些类的实现,甚至名称,你的代码也永远不会注意到。

这被称为 工厂模式


4
2018-05-21 11:18





这就是所谓的 工厂模式

在这种情况下,抽象类还充当负责创建扩展自身的类的具体实例的工厂。

这样,创建正确类的责任就会移交给工厂,工厂通常会根据您传入的某些参数或其他配置/环境等来决定要创建的类。


1
2018-05-21 11:19





谢谢。一旦我对返回的对象的类型进行了测试,我得到了一个派生自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();

            }


  }
}

谢谢大家的答案和意见。


0
2018-05-21 12:46