如果绑定名称是GetType()或ToString()等,则TryInvokeMember不会触发
本文关键字:TryInvokeMember ToString 定名称 绑定 GetType 如果 | 更新日期: 2023-09-27 18:05:29
我只是在摆弄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()
,同样的事情发生了
根据DynamicObject文档:
还可以将自己的成员添加到从DynamicObject类派生的类中。如果你的类定义属性,并覆盖动态语言TrySetMember方法运行时(DLR)首先使用语言绑定器查找属性的静态定义在课堂上。如果没有这样的属性,DLR调用TrySetMember方法。
由于DynamicObject继承自Object, Object的任何方法都将阻止TryInvokeMember处理调用
方法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
上重写这些成员,因为它们被标记为virtual。