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

以下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)’ cannot be accessed with an instance reference;
qualify it with a type name instead

该项目引用了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所指出的,这可能与动态类型无关,因为转换为System.Object也会导致异常.

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

最佳答案

Why is it that DLR does not seem to know which method to invoke and ends up calling the static method object.Equals(object, object)?

因为element.Key不是字符串,而是JToken类型,在调试器中检查它时看起来很像字符串.

这会导致运行时的重载决策选择最佳匹配:static object.Equals(objA, objB),因为它不能调用string.Equals(value, comparisonType),因为第一个参数不是字符串.

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

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

抛出相同的异常.

点赞