开发者

TryInvokeMember doesn't fire if binder name is GetType(), or ToString(), etc

I'm just messing around with the C# 4.0 dynamic keyword, and got curious about one thing.

Suppose I have a class DynamicWeirdness : DynamicObject

Inside it I have a field named reference which is also of type dynamic. And a field named referencetype which is of type Type

This is my constructor:

public DynamicWeirdness(object reference)
{
        this.reference = reference;
        this.referencetype = reference.GetType();
}

If I ever try this:

public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
    if (binder.Name == "GetType" && args.Length == 0)
    {
        result =  referencetype;
        return true;
    }
    result = null;
    return false;
}

When I call GetType() of a DynamicWeirdness object开发者_运维百科, it simply ignores my invocation and returns {Name = "DynamicWeirdness" FullName = "Dynamic1.DynamicWeirdness"}. Why?

I've tried with ToString(), GetHashCode(), and the same thing happens.


According to the documentation for DynamicObject:

You can also add your own members to classes derived from the DynamicObject class. If your class defines properties and also overrides the TrySetMember method, the dynamic language runtime (DLR) first uses the language binder to look for a static definition of a property in the class. If there is no such property, the DLR calls the TrySetMember method.

Since DynamicObject inherits from Object, any methods of Object will preclude TryInvokeMember from processing the call.


The methods GetType(), ToString(), and GetHashCode() are all defined on DynamicObject (since it inherits from System.Object). When .NET goes to invoke those methods, it will just call them directly since they are defined on the object, and will skip the call to TryInvokeMember.

You can see this in action if you try calling a different method, like Substring(), and you'll see that TryInvokeMember on DynamicWeirdness does get called.

Instead of overriding TryInvokeMember on DynamicWeirdness to return a different type, you can just create a new GetType() method on DynamicWeirdness.

public new Type GetType()
{
    return this.referencetype;
}

For GetHashCode() and ToString(), you can override those members on DynamicWeirdness since they are marked as virtual.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜