2010-02-24 53 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