序列化/反序列化System.RuntimeType

时间:2014-07-14 11:41:10

标签: c# serialization types

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

  

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

有没有办法解决这个问题?或者也许还有其他一些存储类型的方法?

1 个答案:

答案 0 :(得分:3)

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(即释放文件系统句柄)。