【问题标题】:Binary deserialize generics二进制反序列化泛型
【发布时间】:2017-03-05 12:45:54
【问题描述】:

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

我通过发送来序列化对象就好了

b.Serialize(fileStream, obj);

但是当试图将文件反序列化回 Listmanager 的实例时,我得到了转换错误。该类名为“AnimalManager”,继承自 ListManager。此类包含 Animal 类型的对象列表。怎么想投给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;
    }

【问题讨论】:

  • 你能展示你对OpenBin的调用以及你的序列化吗?
  • 请阅读How to Ask 并提供minimal reproducible example。您没有反序列化为与以前序列化相同的类型,或者您在某处弄乱了Ts,但我们无法从显示的代码中分析这一点。

标签: c# generics serialization


【解决方案1】:

您的问题是如何调用 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?

【讨论】:

  • 但是你不能有一个通用的反序列化方法吗?我希望它适用于我可能实现的任何类型的“ListManager”,而不仅仅是 AnimalManager?
  • 是的,一个更好的主意是指定第二个通用变量。我会更新我的答案
猜你喜欢
  • 1970-01-01
  • 2014-01-04
  • 2010-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-03
  • 2016-09-15
  • 1970-01-01
相关资源
最近更新 更多