为什么我使用Json.NET获取RuntimeBinderException?

时间:2016-05-04 13:23:20

标签: c# json dynamic

以下C#在第2行导致Microsoft.CSharp.RuntimeBinder。 RuntimeBinderException

dynamic element = JsonConvert.DeserializeObject<dynamic>("{ Key: \"key1\" }");
bool match = "key1".Equals(element.Key, StringComparison.InvariantCulture);
  

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:Member   无法使用实例引用访问'object.Equals(object,object)';   使用类型名称来限定它

该项目引用了Json.NET 8.0.3

<package id="Newtonsoft.Json" version="8.0.3" targetFramework="net452" />

我可以通过明确地将element.Key转换为System.String来绕过异常。

bool match = "key1".Equals((string)element.Key, StringComparison.InvariantCulture);

选中element.Key.GetType()时,会返回Newtonsoft.Json.Linq.JValue

为什么DLR似乎不知道调用哪个方法并最终调用静态方法object.Equals(object, object)

编辑:

正如Amit Kumar Ghosh所指出的,这可能与dynamic类型无关,因为转换为System.Object也会导致异常。

bool match = "key1".Equals((object)element.Key, StringComparison.InvariantCulture);

2 个答案:

答案 0 :(得分:1)

  

为什么DLR似乎不知道调用哪个方法并最终调用静态方法object.Equals(object,object)?

因为element.Key不是string,而是类型为JToken,因此在调试器中检查时看起来非常像字符串。

这会导致运行时的重载分辨率选择最佳匹配:static object.Equals(objA, objB),因为它无法调用string.Equals(value, comparisonType),因为第一个参数isn&# 39; ta string。

您可以使用任何动态对象的非字符串属性重现此:

dynamic foo = new { Foo = false };
bool equals = "Bar".Equals(foo.Foo, StringComparison.InvariantCulture);

引发同样的例外。

答案 1 :(得分:0)

您是否尝试过使用ExpandoObject?

dynamic element = new ExpandoObject();
        element = JsonConvert.DeserializeObject<ExpandoObject>("{ Key: \"key1\" }");            
        bool match = "key1".Equals(element.Key, StringComparison.InvariantCulture); 

示例:https://blogs.msdn.microsoft.com/csharpfaq/2009/09/30/dynamic-in-c-4-0-introducing-the-expandoobject/