代码之家  ›  专栏  ›  技术社区  ›  Matt Whitfield

能够定义静态扩展方法的替代方法

  •  0
  • Matt Whitfield  · 技术社区  · 15 年前

    我知道我不能扩展C中的静态类,我不能 真正地 明白原因,但我确实明白 那个 这是不可能的。

    因此,考虑到这一点,我希望实现以下目标:

    public static class GenericXmlSerialisationExtender
    {
        public static void WriteToXML<T>(this T targetObject, string fileName)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            using (TextWriter writer = new StreamWriter(fileName, false, Encoding.UTF8))
            {
                serializer.Serialize(writer, targetObject);
            }
        }
    
        public static T ReadFromXML<T>(string fileName)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            using (TextReader reader = new StreamReader(fileName, Encoding.UTF8))
            {
                return (T)serializer.Deserialize(reader);
            }
        }
    }
    

    例如,我想为实例定义.writeToXML(我需要使用很多配置/静态数据类,这些类只使用普通的XML序列化),然后为类型定义.readFromXML。

    所以我可以有效地称之为:

    MyType typeInstance = MyType.ReadFromXML(path_to_data);
    

    什么是“合适的”封装方法?我曾经和一个同事一起工作,他认为“代码重用”是复制和粘贴,我不想把自己放在那个括号里!

    2 回复  |  直到 15 年前
        1
  •  2
  •   Simon P Stevens    15 年前

    您将以您已经完成的方式定义它,但要调用它,您将使用标准静态方法调用:

    MyClass deserializedObject = GenericXmlSerialisationExtender.ReadFromXML<MyClass>(@"c:\filename.xml");
    

    (如果这样做,您可能希望为GenericXMLSerialisationExtender类提供一个更合适的名称,或者将其移动到其他静态类)


    扩展方法不能在静态方法上工作的原因是没有对象可以附加扩展方法。

    在您的示例中:

    public static T ReadFromXML<T>(string fileName)
    

    这行中没有定义要扩展的类型。扩展方法要求第一个参数是您希望扩展方法作用于的对象。

    扩展方法只是语法上的糖分,是创建静态助手方法的一种好方法。

    在.NET 2.0中,您可以编写:

    public static class StringHelper
    {
        public static String AddFullStop(String data)
        {
            return data + ".";
        }
    }
    
    String input = "test";
    String output = StringHelper.AddFullStop(input);
    

    .NET 3.5使您能够执行此操作:

    public static class StringExtensions
    {
        public static String AddFullStop(this String data)
        {
            return data + ".";
        }
    }
    
    String input = "test";
    String output = input.AddFullStop();
    

    因此,当您想在方便的扩展方法的范围之外做一些事情时,您只需返回到旧的静态助手方法模式。

        2
  •  1
  •   Jon Skeet    15 年前

    我不是在推荐这个,而是作为一个 选项 以下内容:

    public static T ReadFromXML<T>(this T ignored, string fileName)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(T));
        using (TextReader reader = new StreamReader(fileName, Encoding.UTF8))
        {
            return (T)serializer.Deserialize(reader);
        }
    }
    

    打电话:

    MyType typeInstance = default(MyType).ReadFromXml(path_to_data);
    

    这很可怕,但在某种程度上是解决问题的一种方法。

    我怀疑我会 事实上 把它吸干然后做:

    MyType typeInstance = GenericXmlSerialisationExtender.ReadFromXml<MyType>(...);
    

    如果你能给予 GenericXmlSerialisationExtender 一个简单的名字,不应该太痛苦。

    推荐文章