Я перевожу свое приложение из 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)
СвязывательКласс выглядит так:
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));
Это работает так, что TestList в классе TestContainer2 становится заполненным, но атрибуты Enddate и SomeValue вЭкземпляр TestClass2 не десериализован.
Существует ли какой-либо простой способ преобразования ранее сохраненных классов, полученных из Arraylist, в мои новые классы, производные от List <>?Спасибо / Фредрик