1

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

4

2 回答 2

3

根据DynamicObject 的文档

您还可以将自己的成员添加到派生自 DynamicObject 类的类中。如果您的类定义了属性并且还覆盖了 TrySetMember 方法,则动态语言运行时 (DLR) 首先使用语言绑定器在类中查找属性的静态定义。如果没有此类属性,DLR 将调用 TrySetMember 方法。

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

于 2011-08-12T14:19:53.197 回答
2

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

如果您尝试调用不同的方法,例如 ,您可以看到这一点Substring(),并且您会看到TryInvokeMemberonDynamicWeirdness确实被调用了。

无需重写TryInvokeMemberonDynamicWeirdness以返回不同的类型,您只需GetType()DynamicWeirdness.

public new Type GetType()
{
    return this.referencetype;
}

对于GetHashCode()ToString(),您可以覆盖这些成员,DynamicWeirdness因为它们被标记为虚拟。

于 2011-08-12T14:16:02.030 回答