How to serialize List <T> when T is not serializable

Happening:

Pass the unserializable cross parameter to AppDomain.

Below is some method that I want to call in the remote domain.

public RemoteClass { public Test(Class1 obj); public Test(List<Class1> obj); } 

Define:

 Class1 : un-serializable [Serializable] Class2 : Class1 , ISerializable //mark Class2 serializable { //..... } 

The following code used for testing:

 using (MemoryStream s = new MemoryStream()) { BinaryFormatter f = new BinaryFormatter(); f.Serialize(s, obj); } 

Test result:

 obj result Class1 obj=new Class1(); exception Class1 obj=new Class2(); success List<Class1> obj=new List<Class1); exception when obj contain some element; obj.Add(new Class1(); List<Class1> obj=new List<Class1); exception when obj contain some element; //how??? obj.Add(new Class2(); List<Class2> obj=new List<Class2); success; obj.Add(new Class2(); 

Class1 is not serializable calss, and I cannot change it, so I define Class2, which inherits Class1 and implements ISerializable. I can pass an instance of Class2 when the method needs an instance of Class1 as a result of the test, and this solution is successful, however for List<Class1> this does not work.

+4
source share
8 answers

How to convert an instance of List<Class1> to a List<Class2> (the following should work until you declare a suitable constructor on Class2 ):

 // using System.Linq; List<Class1> inputList = MyInputList(); List<Class2> outputList = inputList.ConvertAll<Class2>(a => new Class2(a)); 

After that, you can simply serialize the List<Class2> .

You will find that you need to convert your serialized list back to List<Class> before you can use it at any place where List<Class1> . A variation of the above should work just as well.

+3
source

Try creating a serialization surrogate for List<Class1> .

+3
source

You cannot serialize List<T> when T not serializable.

+2
source

When serializing an object, all child objects must also be serialized.

List<T> is serializable, but it can be serialized if T also serializable. I do not think there are exceptions to this rule.

What reason do you have for T not to be serializable? In most cases, all you have to do is add [Serializable] above the class name and all you have to do!

0
source

Built-in BinaryFormatter does not support this. If you want to serialize classes that are not marked as Serializable , you need to create your own serializer that does not check the Serializable attribute.

This, of course, will be a great job.

0
source

If by serialization you mean, convert it to a binary sort format. You can do it manually using reflection. It's complicated, but can be done, even more efficiently, than built-in binary serialization.

If you want to use the standard binary .Net serialization, you're out of luck if you don't want to add the [Serializable] attribute of T or implement ISerializable on T.

If you are interested in manually coding a serializer, you can see some code that I use for Media Browser. This gets complicated depending on how complex the objects you want to support are. I would not recommend writing your own serializer, if absolutely necessary.

0
source

You cannot use BinaryFormatter - it will not allow you if the base type is not (/) serializable. However, you could serialize in xml and just pass a string or byte [] - the XmlSerializer less specific:

 using System.Collections.Generic; using System.IO; using System.Xml.Serialization; using System; public class Class1 { } public class Class2 : Class1{} static class Program { static void Main() { List<Class2> c2 = new List<Class2>(); var ser = new XmlSerializer(typeof(List<Class1>), new[] {typeof(Class1), typeof(Class2)}); List<Class1> objects = new List<Class1>(), clone; objects.Add(new Class2()); objects.Add(new Class2()); objects.Add(new Class2()); using (var ms = new MemoryStream()) { ser.Serialize(ms, objects); ms.Position = 0; clone = (List<Class1>)ser.Deserialize(ms); } Console.WriteLine(clone.Count); } } 

Obviously, the difference is that the XmlSerlializer sends public elements, not fields. I also know that my own serializer can do this for you if you want to use a binary.

0
source

If the buildIn serializer is not capable of what you want, try an alternative: sharpserializer

0
source

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


All Articles