我只是在弄混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(),并且发生相同的事情。

最佳答案

方法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上的那些成员,因为它们被标记为虚拟成员。

10-06 12:31