Проблемы с пользовательской десериализацией списка в C # - PullRequest
1 голос
/ 30 июня 2009

Я пишу пользовательский десериализатор, который десериализует список, десериализуя каждый из отдельных объектов в коллекции и затем собирая его вместе.

В основном мой код выглядит так:

//myField is a FieldInfo that represents the field we want to put the data in
//resultObject is the object we want the data to go into

List<Object> new_objects = new List<Object>();
foreach (String file_name in file_name_list)
{
     Object field_object = MyDeserialization(file_name)
     new_objects.Add(field_object)
}
myField.SetValue(resultObject, new_objects);

Но это выдает ошибку SetValue, потому что (например) я пытаюсь поместить List (Object) в List (Int32). Обратите внимание, что эта проблема возникает только с коллекциями. Следующий код:

Object new_object = MyDeserialization(file_name)
myField.SetValue(resultObject, new_object)

работает просто отлично при условии, что тип времени выполнения результата MyDeserialization (file_name) фактически совместим с типом myField. В чем здесь проблема, и есть ли способ заставить десериализацию коллекции работать? (Я попытался заменить объявление List (Object) на myField.FieldType, и оно даже не скомпилируется.

Ответы [ 2 ]

0 голосов
/ 30 июня 2009

Коллекции не предлагают ковариации ... a List<int> просто не a List<object> (или v.v.). Таким образом, вам нужно идентифицировать T, например , например (используя FieldInfo.FieldType) - и сначала создать правильный тип списка.

Для удобства после создания может быть проще использовать неуниверсальный интерфейс IList:

Type listType = typeof(List<>).MakeGenericType(itemType);
IList list = (IList)Activator.CreateInstance(listType);
list.Add(...); // etc

Тем не менее, Я должен подчеркнуть - написание полного (и надежного) сериализатора - это большая работа. У вас есть конкретная причина? Многие из встроенных сериализаторов довольно хороши - например, DataContractSerializer - или сторонние, такие как Json.Net , и (если я сам так говорю) protobuf-net .

0 голосов
/ 30 июня 2009

Проблема в том, что .NET не может знать, что ваш список на самом деле является списком. Следующий код должен работать:

//myField is a FieldInfo that represents the field we want to put the data in
//resultObject is the object we want the data to go into

List<MyType> new_objects = new List<MyType>();
foreach (String file_name in file_name_list)
{
     Object field_object = MyDeserialization(file_name)
     new_objects.Add((MyType)field_object)
}
myField.SetValue(resultObject, new_objects);

Для Fun Linq Extra Credit (при условии, что file_name_list имеет значение IEnumerable):

myField.SetValue(resultObject, file_name_list
           .Select(s => MyDeserialization(s))
           .Cast<MyType>()
           .ToList());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...