Reputation: 1807
The following C# causes a Microsoft.CSharp.RuntimeBinder.RuntimeBinderException on line 2.
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
The project references Json.NET 8.0.3
<package id="Newtonsoft.Json" version="8.0.3" targetFramework="net452" />
I'm able to circumvent the exception by explicitly converting element.Key
to a System.String
.
bool match = "key1".Equals((string)element.Key, StringComparison.InvariantCulture);
When checking element.Key.GetType()
, a Newtonsoft.Json.Linq.JValue
is returned.
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)
?
As Amit Kumar Ghosh pointed out, this probably has nothing to do with dynamic
types, since converting to System.Object
also causes the exception.
bool match = "key1".Equals((object)element.Key, StringComparison.InvariantCulture);
Upvotes: 4
Views: 1920
Reputation: 151738
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)?
Because element.Key
isn't a string
, but is of type JToken
, which when inspecting it in the debugger looks an awful lot like a string.
This causes the overload resolution at runtime to pick the best match: the static object.Equals(objA, objB)
, as it can't call string.Equals(value, comparisonType)
, because the first parameter isn't a string.
You can reproduce this with any dynamic object's non-string property:
dynamic foo = new { Foo = false };
bool equals = "Bar".Equals(foo.Foo, StringComparison.InvariantCulture);
Throws the same exception.
Upvotes: 1
Reputation: 121
Have you tried to use ExpandoObject?
dynamic element = new ExpandoObject();
element = JsonConvert.DeserializeObject<ExpandoObject>("{ Key: \"key1\" }");
bool match = "key1".Equals(element.Key, StringComparison.InvariantCulture);
Upvotes: 0