序列化/反序列化System.RuntimeType

本文关键字:RuntimeType System 反序列化 序列化 | 更新日期: 2023-09-27 18:12:43

我有一个类型列表,我需要保存到文件和阅读它之后。我使用DataContractSerializer,但在反序列化期间我得到一个异常:

找不到带参数的构造函数(SerializationInfo,StreamingContext)在isserializable "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
    }

有办法通过这个吗?或者可能有其他存储类型的方法?

序列化/反序列化System.RuntimeType

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

但是由于某种原因,如果你真的想序列化类型本身,那么你就不应该序列化Type对象(很确定它是不可序列化的)。无论如何,序列化Type.FullName代替。加载Types时,使用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被正确清理(即释放文件系统句柄)。