2017-03-05 122 views
0

我想反序列化ListManager類型的對象,但嘗試時得到一個轉換錯誤。林不知道我做錯了什麼。二進制反序列化的泛型

我在

b.Serialize(fileStream, obj); 

發送但是,試圖反序列化文件回到Listmanager我得到施展錯誤的實例時序列化對象就好了。該類被稱爲「AnimalManager」,並從ListManager繼承。該類包含Animal類型的對象列表。它怎麼會想要施放給動物,而不是Listmanager?

「AnimalManager」類型的對象不能轉換爲「Animal」類型的對象。

public static T OpenBin<T>(string filePath) 
{ 
    FileStream fileStream = null; 
    object obj; 

    try 
    { 
     if (!File.Exists(filePath)) throw new FileNotFoundException("The file" + " was not found. ", filePath); 

     fileStream = new FileStream(filePath, FileMode.Open); 

     var b = new BinaryFormatter(); 

     obj = b.Deserialize(fileStream); 
    } 

    finally 
    { 
     fileStream?.Close(); 
    } 

    return (T)obj; 
} 

[Serializable] 
public class ListManager<T> : IListManager<T> 
{ 
    private List<T> _mList; 

    public ListManager() 
    { 
     _mList = new List<T>(); 
    } 
} 

[Serializable] 
public class AnimalManager : ListManager<Animal> 
{ 
} 

從Form1中調用:

private void button4_Click(object sender, EventArgs e) 
    { 
     var filepath = "test.bin"; 

     if (manager.BinaryDeSerialize(filepath)) 
     { 
      MessageBox.Show("hhohjo"); 
     } 
    } 

要ListManager實例(AnimalManager)

public bool BinaryDeSerialize(string fileName) 
    { 
     var test = BinSerializerUtility.OpenBin<T>(fileName); 

     return true; 
    } 
+2

你能告訴你的OpenBin的通話,以及您的序列? –

+1

請閱讀[問]並提供[mcve]。你不是反序列化成你用來序列化的同一類型,或者你在某處搞亂了'T',但是我們不能從所示的代碼中分析這個。 – CodeCaster

回答

2

你的問題是你如何調用OpenBin。您傳遞給OpenBin的通用類型是您在ListManager中存儲的類型。這意味着當序列化可能正在工作時,您的反序列化嘗試將對象轉換爲類型T,在AnimalManager的情況下爲Animal。一個解決方案是使OpenBin非泛型,但使其在AnimalManager中進行抽象和實現,因此您可以投射到AnimalManager而不是T.

更好的解決方案是爲OpenBin提供第二個通用變量。 T由容器的元素使用,所以指定一個不同的靜態功能,像這樣:

public static E OpenBin<E>(string filePath) 

你將不得不當你雖然調用函數指定類型,就像這樣:

var test = BinSerializerUtility.OpenBin<AnimalManager>(fileName); 

這些方法的問題是您必須在子類中提供類型。

這可以提供一種使用反射來做到這一點的父類:

How do I use reflection to call a generic method?

+0

謝謝你的回覆! –

+0

但是,您是否可以不使用通用的deseralization方法呢?我希望這可以用於我可能實現的任何類型的「ListManager」,而不僅僅是AnimalManager? –

+0

是的,更好的辦法是指定第二個通用變量。我會更新我的答案 –

相關問題