2017-08-28 17 views
1

我有一个对象,其中包含几个字典类型的被序列化到一个JSON如何投放实例化concurrentdictionary到IDictionary的

public class Foo 
{ 
    public Dictionary<string, bool> SomeDict {get;set;} 
    public ConcurrentDictionary<string, complextype> SomeconcurrentDict {Get;set;} 
} 

现在,当我this answer explains需要一个转换器这样做。使用该答案作为示例,我创建了以下内容,以便它可以应用于字典和并发字典。

public class JsonDictionaryConverter<k, v> : CustomCreationConverter<IDictionary<k, v>> 
{ 
    public override IDictionary<k, v> Create(Type objectType) 
     => Activator.CreateInstance(objectType) as IDictionary<k, v>; 

    // in addition to handling IDictionary<string, object>, we want to handle the deserialization of dict value, which is of type object 
    public override bool CanConvert(Type objectType) => objectType == typeof(object) || base.CanConvert(objectType); 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     if (reader.TokenType == JsonToken.StartObject || reader.TokenType == JsonToken.Null) 
      return base.ReadJson(reader, objectType, existingValue, serializer); 

     // if the next token is not an object 
     // then fall back on standard deserializer (strings, numbers etc.) 
     return serializer.Deserialize(reader); 
    } 
} 

但是由于as铸造IDictionary<k,v>失败,并导致NULL,而不是一个IDictionary,我碰上一个空引用异常的路线。

然而,激活器创建对象是一个ConcurrentDictionary,具有匹配的K和V值,这使得我认为应该可以将其转换为as IDictionary<k,v>

那么激活器如何将实例化对象转换为IDictionary<k,v>

应用该属性后,该类看起来如下所示。

public class Foo 
{ 
    [JsonConverter(typeof(JsonDictionaryConverter<string,bool>))] 
    public Dictionary<string, bool> SomeDict {get;set;} 

    [JsonConverter(typeof(JsonDictionaryConverter<string,complextype>))] 
    public ConcurrentDictionary<string, complextype> SomeconcurrentDict {Get;set;} 
} 

.netfiddler简化测试场景似乎运行的代码就好了,结果很好地创建的对象。

在我的本地机器,采用了几乎相同的对象但是,这导致nullrefference例外由于导致NULL投

public class Settings 
{ 
    [JsonConverter(typeof(JsonDictionaryConverter<string,string>))] 
    public ConcurrentDictionary<string, string> Prefix { get; set; } 

    [JsonConverter(typeof(JsonDictionaryConverter<string,bool>))] 
    public ConcurrentDictionary<string, bool> AllowMentions { get; set; } 

    public BotSettings() 
    { 
     Prefix = new ConcurrentDictionary<string, string>(); 
     AllowMentions = new ConcurrentDictionary<string, bool>(); 
    } 

    public Settings LoadSettings() 
    { 
     Settings settings = null; 

// Temporary hardcoded json, for debug purposes 
     if (File.Exists(file)) 
      settings = Serializer.DeserializeJson<BotSettings>("{\"Prefix\":{\"164427220197179403\":\".\",\"342638529622310925\":\".\"},\"AllowMentions\":{\"164427220197179403\":true,\"342638529622310925\":true}}");//string.Join(" ", ReadLines(file))); 

     return settings; 
    } 
} 
+0

你确定'k'和'​​v'是正确的类型(它们与你班里的定义相匹配)吗? –

+0

['IDictionary dict = new ConcurrentDictionary ();'](https://github.com/Microsoft/referencesource/blob/master/mscorlib/system/collections/Concurrent/ConcurrentDictionary.cs#L60)? –

+0

@PatrickHofman绝对。分别为。还使用和各自的并发字典的单个实例对其进行了测试,但结果相同。 –

回答

1

原来这不是Create导致异常。但该方法调用创建代替:

return base.ReadJson(reader, objectType, existingValue, serializer); 

这似乎是在旧版本NewtonSoft,它得到了升级到10.0.3最新版本解决的问题。这也是小提琴确实工作正常的原因,因为这确实使用了较新的版本,而不是我自己的项目。