首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用StringComparer反序列化JSON字典

用StringComparer反序列化JSON字典
EN

Stack Overflow用户
提问于 2017-09-25 20:09:18
回答 3查看 3.7K关注 0票数 12

我试图序列化/反序列化一个字典,问题是我用一个StringComparer.OrdinalIgnoreCase比较器创建了字典。

下面是我正在经历的问题的代码片段:

代码语言:javascript
复制
var dict = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);

dict["x"] = new Dictionary<string, string>();
dict["x"]["y"] = "something";

var serialized = JsonConvert.SerializeObject(dict);

var unSerialized = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>(serialized);

Console.WriteLine((dict.Comparer == unSerialized.Comparer ? "Same" : "Different"));

(.NET Fiddle -试试看)

在控制台上打印以下内容:

Different

显然,JSON序列化程序没有序列化我在创建字典时设置的比较器,但问题是,由于Dictionary.Comparer是只读的,所以无法在事实之后设置比较器。

我确信这与一些定制的JsonSerializerSetting有关,但我似乎不知道如何截取集合创建,并返回一个具有不同比较器的字典。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-09-25 20:21:45

还可以使用PopulateObject填充现有对象。

代码语言:javascript
复制
var dict = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);

dict["x"] = new Dictionary<string, string>();
dict["x"]["y"] = "something";

var json = JsonConvert.SerializeObject(dict);


var result =  new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);
JsonConvert.PopulateObject(json, result);

Console.WriteLine(result["x"]["y"]);
Console.WriteLine(result.Comparer == dict.Comparer ? "Same" : "Diff");

输出:

代码语言:javascript
复制
something
Same
票数 13
EN

Stack Overflow用户

发布于 2017-09-25 20:20:26

如果将反序列化的结果和要使用的比较器传递给新字典的构造函数,则可以在字典的构造函数中指定要使用的比较器:

代码语言:javascript
复制
var deserialized = JsonConvert
    .DeserializeObject<Dictionary<string, Dictionary<string, string>>>(serialized);

var withComparer = new Dictionary<string, Dictionary<string, string>> (
    deserialized, StringComparer.OrdinalIgnoreCase);
票数 11
EN

Stack Overflow用户

发布于 2017-09-25 21:14:53

现在可能有点晚了,但是使用JsonConverter扩展生成的JSON可能会更复杂,但更灵活。我已经为所描述的案例创建了一个示例,它不是满的

.NET Fiddle -试试看

(如果您决定使用它,请随意扩展):

代码语言:javascript
复制
public class DictConverter<TValue> : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var obj = JToken.ReadFrom(reader);                
        if (objectType == typeof(Dictionary<string, TValue>))
        {
            var comparer = obj.Value<string>("Comparer");
            Dictionary<string, TValue> result;
            if (comparer == "OrdinalIgnoreCase")
            {
                result = new Dictionary<string, TValue>(StringComparer.OrdinalIgnoreCase);
            }
            else
            {
                result = new Dictionary<string, TValue>();
            }
            obj["Comparer"].Parent.Remove();
            serializer.Populate(obj.CreateReader(), result);
            return result;
        }
        return obj.ToObject(objectType);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var obj = JObject.FromObject(value);
        if (value is Dictionary<string, TValue>)
        {
            if((value as Dictionary<string, TValue>).Comparer == StringComparer.OrdinalIgnoreCase)
                obj.Add("Comparer", JToken.FromObject("OrdinalIgnoreCase"));
        }
        obj.WriteTo(writer);

    }
}

和使用

代码语言:javascript
复制
var dict = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);

dict["x"] = new Dictionary<string, string>();
dict["x"]["y"] = "something";

var serialized = JsonConvert.SerializeObject(dict, 
    new DictConverter<Dictionary<string,string>>());
var unSerialized = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>
    (serialized, new DictConverter<Dictionary<string, string>>());
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46413406

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档