【问题标题】:Serializing a List<object>序列化列表<object>
【发布时间】:2014-07-18 08:03:55
【问题描述】:

我有一个对象类型的通用列表,我正在尝试对其进行序列化,但反序列化并没有给我带来好的结果。 这是我想要做的:

List<object> sample_list = new List<object>();
        sample_list.Add(new Sample() {  type=0,message="I am the first"});
        sample_list.Add(new Sample1() { type=1,message1 = "I am the 2" });
        sample_list.Add(new Sample2() { type=2,message2 = "I am the 3" });

       string serial= JsonConvert.SerializeObject(sample_list);

       List<object> list = JsonConvert.DeserializeObject<List<object>>(serial);
       lstbox.ItemsSource = list;

       foreach(var item in list)
       {
            if (item is Sample)
            {
                MessageBox.Show("Item is sample");
            }
       }

但消息框永远不会显示。 应该怎么做才能正常工作?

【问题讨论】:

  • 您是否调试过应用程序?
  • 你为什么要序列化然后反序列化?
  • @adaam 如果您想检查您是否以允许您正确反序列化的方式序列化数据,这是很常见的事情......

标签: c# xml json


【解决方案1】:

您正在将列表反序列化为object 的列表,为什么您希望CLR 将这些对象识别为SampleSample1?序列化的 JSON 外观:

[{"type":0,"message":"I am the first"},{"type":1,"message1":"I am the 2"},{"type":2,"message2":"I am the 3"}]

那么 JSON.NET 是如何神奇地发现它们是 Sample 对象呢?做一个简单的测试,注意list[0].GetType().FullNameNewtonsoft.Json.Linq.JObject,而不是Sample

如果你想反序列化到Sample的列表,写:

var list = JsonConvert.DeserializeObject<List<Sample>>(serial);

然后 Json.NET 将尝试将 JSON 中的每个属性匹配Sample 属性(当然,有时它不会成​​功,因为对象不是Sample 类型)。

如果你想序列化你的列表,你的 JSON 应该存储有关使用类型的信息,并且在 JSON.NET 中有内置选项:

string serial = JsonConvert.SerializeObject(sample_list,
    new JsonSerializerSettings { 
        TypeNameHandling = TypeNameHandling.Objects 
    });

然后序列化的 JSON 看起来:

[{"$type":"ConsolePusher.Sample, ConsolePusher","type":0,"message":"I am the first"}, 
 {"$type":"ConsolePusher.Sample1, ConsolePusher","type":1,"message1":"I am the 2"},
 {"$type":"ConsolePusher.Sample2, ConsolePusher","type":2,"message2":"I am the 3"}]

所以它在反序列化时将能够重新创建对象:

var list = JsonConvert.DeserializeObject<List<object>>(serial,
        new JsonSerializerSettings
        {
            TypeNameHandling = TypeNameHandling.Objects
        });

【讨论】:

  • 你的“修复”几乎肯定行不通,因为实例不是全部Sample;一个是Sample,一个是Sample1,一个是Sample2
【解决方案2】:

这里的线索应该是json:

[{"type":0,"message":"I am the first"},
 {"type":1,"message1":"I am the 2"},
 {"type":2,"message2":"I am the 3"}]

您将其反序列化为List&lt;object&gt;。所以:在 json 或 API 调用中没有 nothing 提示您需要 Sample。如果您希望它存储类型名称并在反序列化期间使用它,您需要启用该选项

var settings = new JsonSerializerSettings {
    TypeNameHandling = TypeNameHandling.Objects
};
string serial = JsonConvert.SerializeObject(sample_list, settings);

List<object> list =
    JsonConvert.DeserializeObject<List<object>>(serial, settings);

请注意,存储类型名称是脆弱的并且是特定于实现的;它不会在所有情况下都能正常工作。这里的json变成:

[{"$type":"Sample, ConsoleApplication43","type":0,"message":"I am the first"},
 {"$type":"Sample1, ConsoleApplication43","type":1,"message1":"I am the 2"},
 {"$type":"Sample2, ConsoleApplication43","type":2,"message2":"I am the 3"}]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-20
    • 1970-01-01
    • 1970-01-01
    • 2014-05-19
    • 1970-01-01
    相关资源
    最近更新 更多