我只是搞乱了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;
}
当我调用GetType()
对象的DynamicWeirdness
时,它会忽略我的调用并返回{Name = "DynamicWeirdness" FullName = "Dynamic1.DynamicWeirdness"}
。为什么呢?
我尝试使用ToString()
,GetHashCode()
,同样的事情发生了。
答案 0 :(得分:3)
根据documentation for DynamicObject:
您还可以将自己的成员添加到从DynamicObject类派生的类中。如果你的 class定义属性并覆盖TrySetMember方法,即动态语言 运行时(DLR)首先使用语言绑定器来查找属性的静态定义 在课堂里。如果没有这样的属性,DLR将调用TrySetMember方法。
由于DynamicObject继承自Object,因此Object的任何方法都会阻止TryInvokeMember处理该调用。
答案 1 :(得分:2)
方法GetType()
,ToString()
和GetHashCode()
都在DynamicObject
上定义(因为它继承自System.Object
)。当.NET去调用这些方法时,它会直接调用它们,因为它们是在对象上定义的,并且会跳过对TryInvokeMember
的调用。
如果您尝试调用其他方法(例如Substring()
),则可以看到此操作,并且您会看到TryInvokeMember
上的DynamicWeirdness
被调用。
您可以在TryInvokeMember
上创建新的DynamicWeirdness
方法,而不是在GetType()
上覆盖DynamicWeirdness
以返回其他类型。
public new Type GetType()
{
return this.referencetype;
}
对于GetHashCode()
和ToString()
,您可以覆盖DynamicWeirdness
上的成员,因为它们被标记为虚拟。