C# TryInvokeMember不';如果绑定器名称为GetType()或ToString()等,则不会激发

C# TryInvokeMember不';如果绑定器名称为GetType()或ToString()等,则不会激发,c#,object,dynamic,tryinvokemember,C#,Object,Dynamic,Tryinvokemember,我只是在玩弄C#4.0动态关键词,对一件事很好奇 假设我有一个类DynamicWeirdness:DynamicObject 在它里面有一个名为reference的字段,它也是dynamic类型。以及名为referencetype的字段,其类型为type 这是我的构造器: public DynamicWeirdness(object reference) { this.reference = reference; this.referencetype = refe

我只是在玩弄C#4.0动态关键词,对一件事很好奇

假设我有一个类
DynamicWeirdness:DynamicObject

在它里面有一个名为
reference
的字段,它也是
dynamic
类型。以及名为
referencetype
的字段,其类型为
type

这是我的构造器:

public DynamicWeirdness(object reference)
{
        this.reference = reference;
        this.referencetype = reference.GetType();
}
如果我试过这个:

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;
}
当我调用
DynamicWeirdness
对象的
GetType()
时,它只会忽略我的调用并返回
{Name=“DynamicWeirdness”FullName=“Dynamic1.DynamicWeirdness”}
。为什么?

我尝试了
ToString()
GetHashCode()
,同样的情况也发生了。

方法
GetType()
ToString()
GetHashCode()
都是在
DynamicObject
上定义的(因为它继承自
System.Object
)。当.NET调用这些方法时,它将直接调用它们,因为它们是在对象上定义的,并且将跳过对
TryInvokeMember
的调用

如果您尝试调用不同的方法,如
Substring()
,您可以看到这一点,并且您将看到
DynamicWeirdness
上的
TryInvokeMember
确实被调用

您可以在
DynamicWeirdness
上创建一个新的
GetType()
方法,而不是覆盖
DynamicWeirdness
上的
TryInvokeMember
以返回不同的类型

public new Type GetType()
{
    return this.referencetype;
}
对于
GetHashCode()
ToString()
,您可以覆盖
DynamicWeirdness
上的那些成员,因为它们被标记为虚拟。

方法
GetType()
ToString()
GetHashCode()
都是在
DynamicObject
上定义的(因为它继承自
System.Object
)。当.NET调用这些方法时,它将直接调用它们,因为它们是在对象上定义的,并且将跳过对
TryInvokeMember
的调用

如果您尝试调用不同的方法,如
Substring()
,您可以看到这一点,并且您将看到
DynamicWeirdness
上的
TryInvokeMember
确实被调用

您可以在
DynamicWeirdness
上创建一个新的
GetType()
方法,而不是覆盖
DynamicWeirdness
上的
TryInvokeMember
以返回不同的类型

public new Type GetType()
{
    return this.referencetype;
}
对于
GetHashCode()
ToString()
,您可以覆盖
DynamicWeirdness
上的那些成员,因为它们被标记为虚拟的。

根据:

您还可以将自己的成员添加到从DynamicObject类派生的类中 类定义属性并重写动态语言TrySetMember方法 运行时(DLR)首先使用语言绑定器查找属性的静态定义 如果没有这样的属性,DLR将调用TrySetMember方法

由于DynamicObject继承自Object,Object的任何方法都将阻止TryInvokeMember处理调用。

根据:

您还可以将自己的成员添加到从DynamicObject类派生的类中 类定义属性并重写动态语言TrySetMember方法 运行时(DLR)首先使用语言绑定器查找属性的静态定义 如果没有这样的属性,DLR将调用TrySetMember方法


由于DynamicObject继承自Object,Object的任何方法都将阻止TryInvokeMember处理调用。

+1完全有意义。希望我能将两个答案都标记为答案。+1完全有意义。希望我能将两个答案都标记为答案。