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

12

我只是想澄清一下我的理解,特别是对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个回答

9
你不能使用 new 创建实例,但这里所使用的 Create 是一种静态工厂方法; 它不是构造函数。 事实上,你会发现由 Create 返回的对象并不属于 abstract class XmlWriter,而是属于其他的具体子类。

参见


4
你得到的对象并不抽象。在.NET框架中有13个类实现了XmlWriter,它们都是内部的,只有通过反编译才能看到它们的名称。
不需要自己知道这13个类的名称对你和Microsoft都非常有价值。对你来说,因为你不必学习选择正确类的细节。对于Microsoft来说,因为他们可以完全改变这些类的实现,甚至是名称,而你的代码永远不会注意到。
这被称为工厂模式

1

这就是所谓的 工厂模式

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

这样,创建正确类的责任被移交给了工厂,通常情况下,工厂会根据您传入的某些参数或其他诸如配置/环境等内容来决定创建哪个类。


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

            }


  }
}

感谢大家的回答和建议。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接