Serialize / Deserialize System.RuntimeType

I have a list of types that I need to save to a file and read after it. I am using DataContractSerializer , but when deserializing I get an exception:

Unable to find constructor with arguments (SerializationInfo, StreamingContext) in ISerializable "System.RuntimeType".

I added System.RuntimeType as a known type for my serializer, but that didn't help.

Here is the code of my two methods

 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); } 

Serialization seems fine and the output file is fine, but the problem starts with deserialization:

  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 } 

Is there any way to get through this? Or maybe there is another way to store types?

+6
source share
1 answer

Mark Gravell is right, you should probably serialize data, not types.

But for some reason, if you really want to serialize the types themselves, then you should not serialize the Type object (pretty sure that it cannot be programmed). Anyway, serialize Type.FullName . When you load types, use 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()) } pubic 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)); } } 

Note. When working with any Stream (or indeed any IDisposable ), you need to either call the Dispose method or use the using statement (as I said above). This ensures that IDisposable properly cleaned (i.e., frees file system descriptors).

+2
source

Source: https://habr.com/ru/post/972168/


All Articles