简体   繁体   English

C#中列表的自定义反序列化问题

[英]Problems with custom deserialization of a list in C#

I'm writing a custom deserializer that will deserialize a list by deserializing each of the individual objects in the collection and then putting it together. 我正在编写一个自定义反序列化器,该序列化器将通过反序列化集合中的每个单个对象然后将其放在一起来反序列化列表。

Basically my code looks like this: 基本上我的代码如下所示:

//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);

But this gives an error on the SetValue because (for example) I am trying to put a List(Object) into a List(Int32). 但这在SetValue上产生错误,因为(例如)我试图将List(Object)放入List(Int32)。 Note that this problem only occurs with collections. 请注意,此问题仅在集合中发生。 The following code: 如下代码:

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

works just fine provided that the runtime type of the result of MyDeserialization(file_name) is actually compatible with the type of myField. 只要MyDeserialization(file_name)结果的运行时类型实际上与myField的类型兼容,就可以正常工作。 What is the problem here, and is there a way to make the collection deserialization work? 这是什么问题,有没有办法使集合反序列化工作? (I've tried replacing the List(Object) declaration with myField.FieldType and that won't even compile. (我已经尝试用myField.FieldType替换List(Object)声明,并且它甚至不会编译。

The problem is that .NET can't know that your List is actually a List. 问题是.NET无法知道您的列表实际上是一个列表。 The following code should work: 下面的代码应该工作:

//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);

For Fun Linq Extra Credit (assuming file_name_list is IEnumerable): 对于Fun Linq Extra Credit(假设file_name_list是IEnumerable):

myField.SetValue(resultObject, file_name_list
           .Select(s => MyDeserialization(s))
           .Cast<MyType>()
           .ToList());

Collections do not offer covariance... a List<int> simply isn't a List<object> (or vv). 集合不提供协方差... List<int>根本不是 List<object> (或vv)。 As such, you need to identify the T , for example like so (using the FieldInfo.FieldType ) - and create the right type of list in the first place. 这样,您需要标识T ,例如像这样 (使用FieldInfo.FieldType )-首先创建正确的列表类型。

For convenience, once created it may be simpler to use the non-generic IList interface: 为方便起见,创建后,使用非通用IList接口可能会更简单:

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

However; 然而; I must stress - writing a full (and robust) serializer is a lot of work. 我必须强调-编写完整(且健壮)的序列化器需要大量工作。 Do you have a specific reason? 您有特定原因吗? Many of the inbuilt serializers are pretty good - for example DataContractSerializer - or 3rd party, such as Json.Net , and (if I do say so myself) protobuf-net . 许多内置的序列化器都非常好-例如DataContractSerializer-或第3方,例如Json.Net ,以及(如果我自己也这么说的话) protobuf-net

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM