2010-02-24 56 views
0

我的理解是我不能在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

你会在完全相同你已经做的方式定义它,而是把它你可以使用一个标准的静态方法调用:

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

所以,当你想要做的得心应手扩展方法的范围之外的东西,你只是回落到旧的静态辅助方法模式。

+0

你在哪里说“是没有对象将扩展方法附加到” - 这是我*不了解的位。为什么将它扩展到你所建议的代码是一个非常大的飞跃?不是议论性的,只是想实际理解*为什么* ... – 2010-02-24 09:38:12

+0

@Matt:因为您尚未指定要在扩展方法签名中扩展的“类型”。扩展方法将出现在哪种类型? (在你的情况下,你实际上只想扩展“Object”,但事实并非总是如此,你如何告诉编译器你希望你的静态扩展方法出现在Strings上)。这将需要C#设计团队添加更多语法更改,以允许您指定想要静态扩展的类型。 – 2010-02-24 09:42:23

+0

我想C#团队可以实现这种新的语法,但这是一个很不寻常的例子。添加了扩展方法来支持非常常见的“静态帮助类”模式。他们通常不会对语法进行修改,只是为了支持像您所建议的那样的不寻常边缘案例。它实际上并没有给你带来任何可读性,编写String.HelperMethod()之间没有太大的区别。或StringHelper.Method(); – 2010-02-24 09:45:41

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迅捷的名字,这不应该是太痛苦了。

+0

谢谢...你能阐明为什么编译器不能将它扩展到实际执行的方式(这是我期望它会做的)吗?只是为了我的理解真的...... – 2010-02-24 09:39:30

+0

@Matt:你试图添加一种根本不存在的继承,真的。我敢说这种语言可能是按照这些思路设计的,但它可能会在各个地方增加额外的复杂性。 – 2010-02-24 09:43:35

+0

乔恩 - 谢谢 - 你能否推荐任何优秀的阅读材料来确切地说明为什么它不被支持?因为据我所知,所有支持语法的元素都已经存在了......所以我想我应该错过一些东西。 – 2010-02-24 09:51:36