我正在使用ArrayLists转换我的应用程序以开始使用List<>
我之前发过关于这个主题的帖子,但确实留下了很多细节。这是一篇新帖子,其中包含完整的详细信息以及从另一个角度描述的问题。
在转换之前,代码看起来与此类似:
[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
此时,保存了一个TestContainer1实例,其中包含TestClass1实例(TestList属性)。此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)
binder类看起来像:
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属性。
是否存在将我以前保存的Arraylist派生类转换为我的新List&lt;&gt; -derived类的简单方法? 谢谢 /弗雷德里克
答案 0 :(得分:1)
我有一种感觉,你想要做的事情是不可能的。我建议您在解决方案中保留旧TestClass1的副本,并编写一个手动转换器,通过标准属性赋值将反序列化的TestClass1转换为TestClass2。
如果TestContainer1成功反序列化为TestContainer2,则可以将TestClass1到TestClass2的转换挂钩到TestContainer2的OnDeserializing上。