我有一个对象,它包含几个被序列化为Json的字典类型
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 :(得分:1)
原来不是引起异常的Create
。但是调用Create的方法是:
return base.ReadJson(reader, objectType, existingValue, serializer);
这似乎是旧版NewtonSoft中的一个问题,它通过升级到最新版本10.0.3得到了解决。这也是Fiddle确实正常工作的原因,因为这确实使用了较新的版本,而不是我自己的项目。