2017-03-05 83 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

是的,更好的办法是指定第二个通用变量。我会更新我的答案 –

相关问题