案例:
将一个不可序列化的参数传递给AppDomain。
以下是我想在远程域中调用的一些方法;
public RemoteClass
{
public Test(Class1 obj);
public Test(List<Class1> obj);
}
定义:
Class1 : un-serializable
[Serializable]
Class2 : Class1 , ISerializable //mark Class2 serializable
{
//.....
}
以下代码用于测试:
using (MemoryStream s = new MemoryStream())
{
BinaryFormatter f = new BinaryFormatter();
f.Serialize(s, obj);
}
测试结果:
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不是可序列化的calss,我无法修改它,因此我定义了继承自Class1并实现ISerializable的Class2。当方法在测试结果中需要Class2
的实例并且此解决方案成功时,我可以传递Class1
的实例,但是对于List<Class1>
,这不起作用。
答案 0 :(得分:3)
如何将List<Class1>
实例转换为列表List<Class2>
(只要您在Class2
上声明合适的构造函数,以下内容就可以正常工作):
// using System.Linq;
List<Class1> inputList = MyInputList();
List<Class2> outputList = inputList.ConvertAll<Class2>(a => new Class2(a));
然后,您应该可以将List<Class2>
序列化。
您发现需要将序列化列表转换回List<Class>
,然后才能在接受List<Class1>
的任何地方使用它 - 上面的变体也应该反过来。< / p>
答案 1 :(得分:3)
尝试为List<Class1>
创建serialization surrogate。
答案 2 :(得分:2)
当List<T>
不可序列化时,您无法序列化T
。
答案 3 :(得分:0)
序列化对象时,所有子对象也必须是可序列化的。
List<T>
是可序列化的,但如果T
也可序列化,则只能对其进行序列化。我不认为这条规则有任何例外。
您有什么理由让T
无法序列化?在大多数情况下,您只需在类名上方添加[Serializable]
,这就是您需要做的一切!
答案 4 :(得分:0)
内置BinaryFormatter
不支持此功能。如果要序列化未标记为Serializable
的类,则需要构建不检查Serializable
属性的自定义序列化程序。
这当然会有很多工作。
答案 5 :(得分:0)
如果通过序列化意味着将其转换为各种二进制格式。您可以使用反射手动执行此操作。它变得棘手但可以完成,甚至比内置的二进制序列化更有效。
如果您想使用标准的.Net binary serialization,那么您运气不好,除非您愿意将[Serializable]
属性添加到T或在T上实现ISerializable。
如果您对手动编码序列化程序感兴趣,可以查看我用于媒体浏览器的some of the code。根据您想要支持的对象的复杂程度,它会变得棘手。除非绝对必要,否则不建议编写自己的序列化程序。
答案 6 :(得分:0)
你不能使用BinaryFormatter
- 除非基类型是(/是)可序列化的,否则它不会让你。但是,您可以序列化为xml并只传递字符串或字节[] - XmlSerializer
不太特别:
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);
}
}
这里的差异显然是XmlSerlializer
发送公共成员,而不是字段。我也知道如果你想要二进制文件,我自己的序列化程序可以为你做这个。
答案 7 :(得分:0)
如果buildIn Serializer无法满足您的需求,请尝试其他选择:sharpserializer