二进制反序列化泛型

时间:2017-03-05 12:45:55

标签: c# generics serialization

我正在尝试反序列化ListManager类型的对象,但在尝试时会出现强制转换错误。我不确定我做错了什么。

我通过发送

来序列化对象
InfoboardManager

但是当试图将文件反序列化回Listmanager的一个实例时,我得到了转换错误。该类称为“AnimalManager”,并继承自ListManager。此类包含Animal类型的对象列表。它怎么想投射到动物而不是Listmanager?

“AnimalManager”类型的对象无法转换为“Animal”类型的对象。

b.Serialize(fileStream, obj);

从Form1调用:

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>
{
}

转到ListManager实例(AnimalManager)

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

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

1 个答案:

答案 0 :(得分: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?