C# 为什么我使用Json.NET获得RuntimeBinderException?

C# 为什么我使用Json.NET获得RuntimeBinderException?,c#,json,dynamic,C#,Json,Dynamic,以下C#导致第2行出现Microsoft.CSharp.RuntimeBinder.RuntimeBinderException dynamic element = JsonConvert.DeserializeObject<dynamic>("{ Key: \"key1\" }"); bool match = "key1".Equals(element.Key, StringComparison.InvariantCulture); 检查element.Key.GetType()

以下C#导致第2行出现Microsoft.CSharp.RuntimeBinder.RuntimeBinderException

dynamic element = JsonConvert.DeserializeObject<dynamic>("{ Key: \"key1\" }");
bool match = "key1".Equals(element.Key, StringComparison.InvariantCulture);
检查
element.Key.GetType()
时,返回一个
Newtonsoft.Json.Linq.JValue

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

编辑: 正如Amit Kumar Ghosh指出的,这可能与
动态
类型无关,因为转换为
系统.Object
也会导致异常

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

您是否尝试过使用ExpandoObject

dynamic element = new ExpandoObject();
        element = JsonConvert.DeserializeObject<ExpandoObject>("{ Key: \"key1\" }");            
        bool match = "key1".Equals(element.Key, StringComparison.InvariantCulture); 
dynamic元素=新的ExpandoObject();
element=JsonConvert.DeserializeObject(“{Key:\“key1\”}”);
bool match=“key1”.Equals(element.Key,StringComparison.InvariantCulture);
例如:

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

因为
元素.Key
不是
字符串
,而是类型
JToken
,当在调试器中检查它时,它看起来非常像字符串

这会导致重载解析在运行时选择最佳匹配:因为它无法调用,因为第一个参数不是字符串

您可以使用任何动态对象的非字符串属性复制该属性:

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

引发相同的异常。

“key1”.Equals((object)element.Key,StringComparison.InvariantCulture)在编译时引发相同的错误。这并不能解释为什么最终调用静态方法object.Equals(object,object)您能否详细说明IDynamicMetaObjectProvider的用途,以及为什么它适用于ExpandoObject,而不适用于JValue?@cookies我真的不理解这个问题。你的问题是为什么使用
反序列化对象
元素的类型。键
JToken
JValue
,而使用
反序列化对象
则是
字符串
?仔细想想,这实际上是有意义的。我想弄清楚JValue是否遗漏了一些可以让这项工作成功的东西。另外,当我调用实例成员时,DLR正在考虑静态成员,这似乎很奇怪。
bool match = "key1".Equals((object)element.Key, StringComparison.InvariantCulture);
dynamic foo = new { Foo = false };
bool equals = "Bar".Equals(foo.Foo, StringComparison.InvariantCulture);