C# 将继承的arraylist反序列化为继承的列表<&燃气轮机;
我正在将我的应用程序从使用ArrayList转换为使用List 我以前曾就这个问题发表过一篇文章,但确实遗漏了很多细节。这是一篇新的文章,详细介绍了这个问题,并从另一个角度进行了描述 在我转换之前,代码看起来类似于:C# 将继承的arraylist反序列化为继承的列表<&燃气轮机;,c#,list,generics,arraylist,C#,List,Generics,Arraylist,我正在将我的应用程序从使用ArrayList转换为使用List 我以前曾就这个问题发表过一篇文章,但确实遗漏了很多细节。这是一篇新的文章,详细介绍了这个问题,并从另一个角度进行了描述 在我转换之前,代码看起来类似于: [Serializable] public class TestContainer1 : ISerializable { public TestContainer1() { TestList.Add(1); TestList.Add(2); Test
[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实例,其中包含一个TestClass1实例(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;
}
我使用绑定器将数据反序列化为具有新名称的类(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的一个实例,它从列表而不是ArrayList继承)变为空
我尝试使用如下代码转换测试列表:
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));
Type unsec=typeof(列表);
Type spec=unspec.MakeGenericType(typeof(int));
object obj=格式化程序。反序列化(ms);
类型ut=((ArrayList)obj)[0].GetType();
objecttypeinst=Activator.CreateInstance(spec,((ArrayList)obj.ToArray(ut));
这是因为TestContainer2类中的TestList已填充,但TestClass2实例中的Enddate和SomeValue属性未反序列化
是否存在将以前保存的Arraylist派生类转换为新的列表派生类的简单方法?
谢谢
/弗雷德里克我觉得你想做的事是不可能的。我建议您在解决方案中保留旧TestClass1的副本,并编写一个手动转换器,通过标准属性分配将反序列化的TestClass1转换为TestClass2
如果TestContainer1成功反序列化为TestContainer2,您可以将TestClass1到TestClass2的转换挂接到TestContainer2的OnDeserialization上。谢谢您的回答。我也有过这样的想法。
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;
}
}
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));