将继承的数组列表反序列化为继承的列表<>
本文关键字:列表 继承 反序列化 数组 | 更新日期: 2023-09-27 18:19:25
我正在转换我的应用程序从使用数组列表开始使用列表<>
我之前写过一篇关于这个主题的文章,但是遗漏了很多细节。这是一篇新的文章,从另一个角度详细描述了这个问题。
在转换之前,代码看起来像这样:
[Serializable]
public class TestContainer1 : ISerializable
{
public TestContainer1()
{
TestList.Add(1);
TestList.Add(2);
TestList.Add(3);
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("List1", TestList);
}
protected TestContainer1(SerializationInfo info, StreamingContext context)
{
TestList = (TestClass1)info.GetValue("List1", typeof(TestClass1));
}
public TestClass1 TestList = new TestClass1();
}
[Serializable]
public class TestClass1 : ArrayList
{
public TestClass1(){}
public DateTime Startdate = DateTime.Today;
public int SomeValue = 127;
}
保存到文件时,使用以下代码(稍微简化):
TestContainer1 tc = new TestContainer1();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, tc); //fs is a file stream
此时,保存了一个包含TestClass1实例(TestList属性)的TestContainer1实例。这个TestList确实包含了3个值(1、2和3)的列表,以及2个属性(Startdate和SomeValue)。
现在,我想用泛型列表来转换我的结构。我的类定义如下:
[Serializable]
public class TestContainer2 : ISerializable
{
public TestContainer2() {}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("List1", TestList);
}
protected TestContainer2(SerializationInfo info, StreamingContext context)
{
TestList = (TestClass2)info.GetValue("List1", typeof(TestClass2));
}
public TestClass2 TestList = new TestClass2();
}
[Serializable]
public class TestClass2 : List<int>//, ISerializable
{
public TestClass2() {}
public DateTime Startdate;
public int SomeValue;
}
类有新的名称,但这只是为了区别于旧版本(TestContainer1和TestClass1)。
当我现在尝试反序列化以前保存的数据时,我使用以下代码:
BinaryFormatter formatter = new BinaryFormatter();
//Deserialize it to a new object
formatter.Binder = new TestTypeBinder();
TestContainer2 tc2 = (TestContainer2)formatter.Deserialize(ms);
我使用绑定器将数据反序列化为具有新名称的类(TestContainer2和TestClass2)
绑定器类如下:
sealed class TestTypeBinder : SerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
Type typeToDeserialize = null;
String typeVer1_1 = "SimDataStorage.DataStorage+TestContainer1";
String typeVer1_2 = "SimDataStorage.DataStorage+TestClass1";
String typeVer2_1 = "SimDataStorage.DataStorage+TestContainer2";
String typeVer2_2 = "SimDataStorage.DataStorage+TestClass2";
if (typeName == typeVer1_1)
typeName = typeVer2_1;
else if (typeName == typeVer1_2)
typeName = typeVer2_2;
typeToDeserialize = Type.GetType(String.Format("{0}, {1}",
typeName, assemblyName));
return typeToDeserialize;
}
}
粘合剂按预期工作。TestContainer2的反序列化函数被调用,TestClass2也被反序列化。
最大的问题是TestList(现在是TestClass2的一个实例,它继承了List而不是ArrayList)变为空。
我已经尝试使用下面的代码来转换TestList:
Type unspec = typeof(List<>);
Type spec = unspec.MakeGenericType(typeof(int));
object obj = formatter.Deserialize(ms);
Type ut = ((ArrayList)obj)[0].GetType();
object typeInst = Activator.CreateInstance(spec, ((ArrayList)obj).ToArray(ut));
在TestContainer2类中的TestList被填充,但是TestClass2实例中的Enddate和SomeValue属性没有被反序列化。
是否存在任何简单的方法来转换我以前保存的数组列表派生类到我的新列表<>派生类?谢谢/弗雷德里克·
我有一种感觉,你想做的事情是不可能的。我建议您在解决方案中保留旧TestClass1的副本,并编写一个手动转换器,通过标准属性赋值将反序列化的TestClass1转换为TestClass2。
如果TestContainer1成功反序列化为TestContainer2,您可以将TestClass1到TestClass2的转换挂接到TestContainer2的OnDeserializing上。