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

时间:2010-02-24 09:16:48

标签: c# generics serialization extension-methods

我明白我不能在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(我需要使用很多配置/静态数据类,只使用vanilla XML Serialization),然后使用.ReadFromXML类型。

如此有效地我可以称之为:

MyType typeInstance = MyType.ReadFromXML(path_to_data);

封装它的“正确”方法是什么?我曾经和一位相信'代码重复使用'的同事一起工作过。粘贴,我宁愿不把自己放在那个支架里!

2 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:1)

我实际上并没有推荐这个,而是作为选项

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一个更快乐的名字,那不应该太痛苦。