【问题标题】:Problems with custom deserialization of a list in C#C#中列表的自定义反序列化问题
【发布时间】:2010-11-06 19:43:21
【问题描述】:

我正在编写一个自定义反序列化程序,它将通过反序列化集合中的每个单独对象然后将它们放在一起来反序列化一个列表。

基本上我的代码是这样的:

//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 的类型兼容,就可以正常工作。这里有什么问题,有没有办法使集合反序列化工作? (我尝试用 myField.FieldType 替换 List(Object) 声明,但它甚至无法编译。

【问题讨论】:

    标签: c# .net reflection serialization


    【解决方案1】:

    问题是.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());
    

    【讨论】:

    • 这行不通,因为 MyType 在编译时是未知的。
    【解决方案2】:

    集合不提供协方差... List&lt;int&gt; 只是不是 List&lt;object&gt;(或 v.v.)。因此,您需要识别T,例如like so(使用FieldInfo.FieldType) - 并首先创建正确类型的列表。

    为方便起见,创建后使用非泛型IList 接口可能更简单:

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

    但是;我必须强调——编写一个完整的(和健壮的)序列化程序是很多工作。你有具体的原因吗?许多内置序列化程序都非常好 - 例如DataContractSerializer - 或第3方,例如Json.Net,和(如果我自己这么说的话)protobuf-net

    【讨论】:

    • 实际上,我并没有真正编写完整的自定义序列化程序。我正在尝试做的是获取一个非常大的对象并将其分解为一大堆较小的对象,这些对象可以在单独的文件中进行序列化。例如,如果对象中的一个字段是 50 条记录的列表,并且每条记录是一个兆字节,如果我想提取一条记录,我希望有一种方法来反序列化我想要的一条记录,而不是而不是用所有 50 条记录反序列化整个对象。然后我的序列化程序会调用一个内置的序列化程序来序列化分解的对象。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多