c# - 序列化/反序列化 System.RuntimeType

标签 c# serialization types

我有一个类型列表,我需要将其保存到文件中并在之后阅读。 我使用 DataContractSerializer 但在反序列化期间出现异常:

Can't find constructor with arguments (SerializationInfo, StreamingContext) in ISerializable "System.RuntimeType".

我已将 System.RuntimeType 作为已知类型添加到我的序列化程序中,但它没有帮助。

这是我的两种方法的代码

public static void SaveTypes(List<Type> types, string fileName)
{
    Type rt = types[0].GetType();

    List<Type> knownTypes = new List<Type>() { rt }; //I get a List with System.RuntimeType item here
    DataContractSerializer serializer = new DataContractSerializer(typeof(List<Type>), knownTypes);
    XmlWriterSettings settings = new XmlWriterSettings();
    settings.Indent = true;
    Stream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write);
    using (XmlWriter xw = XmlWriter.Create(fs, settings))
        serializer.WriteObject(xw, types);
}

序列化似乎工作正常,输出文件没问题,但问题开始于反序列化:

    public static object LoadTypes(string fileName)
    {
        Stream file = new FileStream(fileName, FileMode.Open, FileAccess.Read);
        byte[] data = new byte[file.Length];
        file.Read(data, 0, (int)file.Length);

        Type rt = file.GetType();
        List<Type> knownTypes = new List<Type>() { rt.GetType() };
        DataContractSerializer deserializer = new DataContractSerializer(typeof(List<Type>), knownTypes);

        Stream stream = new MemoryStream();
        stream.Write(data, 0, data.Length);
        stream.Position = 0;
        return deserializer.ReadObject(stream); //exception here
    }

有什么办法可以解决这个问题吗?或者也许有一些其他的方式来存储类型?

最佳答案

Marc Gravell 是对的,您可能应该序列化数据而不是类型。

但出于某种原因,如果您真的想自己序列化类型,那么您不应该序列化 Type 对象(很确定它是不可序列化的)。无论如何,改为序列化 Type.FullName。加载类型时,使用 Type.Load

public static void SaveTypes(IEnumerable<Type> types, string filename)
{
    using (var fs = File.Open(filename, FileMode.OpenOrCreate)
        new XmlSerializer(typeof(string[]))
            .Serialize(fs, types.Select(t => t.FullName).ToArray())
}

public static IEnumerable<Type> LoadTypes(string filename)
{
    using (var fs = File.Open(filename, FileMode.Open)
    {
        var typeNames = (string[])
        new XmlSerializer(typeof(string[]))
            .Deserialize(fs);

        return typeNames.Select(t => Type.Load(t));
    }
}

注意:在使用任何 Stream(或实际上任何 IDisposable)时,您必须调用 Dispose 方法或使用 using 语句(就像我在上面所做的那样)。这可确保正确清理 IDisposable(即释放文件系统句柄)。

关于c# - 序列化/反序列化 System.RuntimeType,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24735739/

相关文章:

c# - 带有 IXmlSerializable 的命名空间前缀

c - 简单的 C 数据类型

ruby - 检查方法参数的类型

c# - 如何检查 IEnumerable<T> 中的 T 是否为接口(interface)?

c# - 如何在 C# 中的 FontWeights 之间使用等于运算符?

c# - 循环递归自连接表

c# - 比较两个平面文件内容的最佳方法

c# - 播种多个随机数生成器

c# - 将 DateTime 序列化覆盖为字符串

在析构函数中创建/写入 PHP 文件