2010-03-09 100 views
3

我想創建一個通用的方法來serizlize類文本(用作網絡組件的一部分) 的方法應該是這樣的:測試一個類可序列化

public string SerializeToText<T>(T DataToSerialize); 

的方法內容將簡單地執行xml序列化,我可以做到這一點。我想知道的是,如果我可以檢查T是否可以被序列化:最好在編譯時,但在運行時失敗。

+0

很確定這是一個騙局,至少有一個答案是一個確切的dupe http:// stackoverflow。com/questions/81674/how-to-check-if-an-object-is-serializable-in-c – 2010-03-09 23:26:19

+0

不是 - 這個問題主要是關於在編譯時檢查的問題。前一個問題只是詢問運行時檢查。這裏的許多答案可能是重複的,但僅僅是因爲他們的作者沒有仔細閱讀這個問題! :) – 2010-03-09 23:28:39

回答

4

單個最可靠的方法來測試,看看對象序列化是序列化它。如果成功,那麼該對象是可序列化的,如果拋出則不可序列化。

注意這不是未來成功的預測因素,而只是過去的成功。對象改變它的狀態當然不可能是可序列化的。例如

[Serialiable] 
class Foo { 
    public object Field; 
} 
class Bar { } 

var value = new Foo() { Field1 = 42; } // value is serializable 
value.Field1 = new Bar(); // value is no longer serializable 

我寫了一篇關於確定對象是否是不可序列化的問題的冗長的博客文章。它深入討論了這種類型的方法的問題。

0

一個類可以用於序列化通過簡單地應用的屬性來定義時被啓用。而且在C#中沒有辦法讓編譯時發生錯誤,因爲類型缺少一個屬性,所以不行,你不能在編譯時嘗試序列化一個不可序列化的類型。

如果使用標準庫方法進行序列化,任何對不支持它的類進行序列化的嘗試都會產生一個異常,所以你不需要做任何特殊的事情來在運行時檢查它。

此外,你的包裝方法通用也有一點點。參數可以是任何類型的,沒有限制,可以有效地限制它,所以它可能是一個普通的舊object。然而,如果你避免了內建的.NET序列化框架,你可以開發自己的編譯時檢查。你必須適當地使用類型系統 - 也就是定義一個任何可串行化類型必須實現的接口。然後您的SerializeToText方法將接受對該接口的引用。

interface ICanSerialize 
{ 
    void Serialize(ISerializeMedium m); 
} 

interface ISerializeMedium 
{ 
    void Serialize(string name, ref int value); 
    void Serialize(string name, ref bool value); 
    void Serialize(string name, ref string value); 
    void Serialize<T>(string name, ref T value) where T : ICanSerialize; 
    void Serialize<T>(string name, ref ICollection<T> value) where T : ICanSerialize; 

    // etc. 
} 

可序列類型應該是這樣的:

class C : ICanSerialize 
{ 
    string _firstName; 
    bool _happy; 

    public void Serialize(ISerializeMedium m) 
    { 
     m.Serialize("firstName", ref _firstName); 
     m.Serialize("happy", ref _happy); 
    } 
} 

然後你只需要的ISerializeMedium的實現。這樣的框架從一開始就對所有序列化的使用進行了類型安全性,而不是試圖在之後使用它,這是不可能的。

這一切都涉及一定數量的車輪改造,但有時你需要一個更圓的車輪。

-1

你是指這個嗎?

if (typeof(T).IsSerializable) 
+0

查看Jared的答案,爲什麼它不那麼簡單。 – 2010-03-09 23:26:57

+0

好的。當JaredPar寫他的答案時,我正在寫答案,這就是爲什麼我沒有在發佈之前閱讀它。 – Javier 2010-03-09 23:32:24