Json.net DeserializeAnonymousType返回BigInteger而不是UInt64

时间:2019-05-04 14:28:25

标签: c# parsing json.net biginteger uint64

假设我们有以下代码:

Type t = typeof(UInt64);
var def = Activator.CreateInstance(t);
Console.WriteLine(def.GetType());

string json = "18446744073709551615";
object parsedObject = JsonConvert.DeserializeAnonymousType(json, def);
Console.WriteLine(parsedObject.GetType());

输出为:

System.UInt64 
System.Numerics.BigInteger

由于我明确地向DeserializeAnonymousType提供了def,其类型为UInt64,因此我也希望UInt64作为输出,尤其是因为18446744073709551615是有效的{{ 1}}值(允许的最大值,但是我也检查了18446744073709551614,它是相同的。)

为什么会这样?我检查了Newtonsoft Github的问题,却一无所获(至少在未解决的问题中没有)。

如何强制使用我事先知道的正确类型(动态地,我只有UInt64)?显然,如果仅发生在System.Type上,我可以进行检查并明确进行转换。

1 个答案:

答案 0 :(得分:2)

您的问题是JsonConvert.DeserializeAnonymousType<T>(string value, T anonymousTypeObject)并没有达到您的期望。它不会将JSON字符串反序列化为T anonymousTypeObject参数的实际类型。它将JSON字符串反序列化为参数的 声明类型 -在您的情况下为 object

这可以从reference source中看到:

public static T DeserializeAnonymousType<T>(string value, T anonymousTypeObject)
{
    return DeserializeObject<T>(value);
}

T anonymousTypeObject从未真正使用过。而是在调用DeserializeAnonymousType时完全通过类型推断来指定目标类型-特别是从代码中变量def的声明类型中进行指定。但是def被隐式声明为object,因为这是Activator.CreateInstance(Type type)声明要返回的内容。因此object就是Json.NET将JSON反序列化为-某种.Net类型足以捕获传入的JSON。由于BigInteger足以捕获传入的JSON,因此Newtonsoft会选择该类型而不是Uint64

如果要强制Json.NET反序列化为特定对象的实际,具体类型,请使用JsonConvert.DeserializeObject(string value,Type type)

object parsedObject = JsonConvert.DeserializeObject(json, def.GetType());

演示小提琴here