如果活页夹名称为GetType()或ToString()等,则不会触发TryInvokeMember

时间:2011-08-12 13:48:46

标签: c# object dynamic tryinvokemember

我只是搞乱了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(),同样的事情发生了。

2 个答案:

答案 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上的成员,因为它们被标记为虚拟。