如果绑定器名称为 GetType() 或 ToString() 等,则 TryInvokeMember 不会触发

发布于 2024-11-29 16:10:57 字数 970 浏览 3 评论 0原文

我只是在摆弄 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;
}

当我调用 a 的 GetType()DynamicWeirdness 对象,它只是忽略我的调用并返回 {Name = "DynamicWeirdness" FullName = "Dynamic1.DynamicWeirdness"}。为什么?

我尝试过使用 ToString()GetHashCode(),并且发生了同样的事情。

I'm just messing around with the C# 4.0 dynamic keyword, and got curious about one thing.

Suppose I have a class DynamicWeirdness : DynamicObject

Inside it I have a field named reference which is also of type dynamic. And a field named referencetype which is of type Type

This is my constructor:

public DynamicWeirdness(object reference)
{
        this.reference = reference;
        this.referencetype = reference.GetType();
}

If I ever try this:

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;
}

When I call GetType() of a DynamicWeirdness object, it simply ignores my invocation and returns {Name = "DynamicWeirdness" FullName = "Dynamic1.DynamicWeirdness"}. Why?

I've tried with ToString(), GetHashCode(), and the same thing happens.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

肥爪爪 2024-12-06 16:10:57

根据 DynamicObject 文档

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

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

According to the documentation for DynamicObject:

You can also add your own members to classes derived from the DynamicObject class. If your
class defines properties and also overrides the TrySetMember method, the dynamic language
runtime (DLR) first uses the language binder to look for a static definition of a property
in the class. If there is no such property, the DLR calls the TrySetMember method.

Since DynamicObject inherits from Object, any methods of Object will preclude TryInvokeMember from processing the call.

似最初 2024-12-06 16:10:57

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

The methods GetType(), ToString(), and GetHashCode() are all defined on DynamicObject (since it inherits from System.Object). When .NET goes to invoke those methods, it will just call them directly since they are defined on the object, and will skip the call to TryInvokeMember.

You can see this in action if you try calling a different method, like Substring(), and you'll see that TryInvokeMember on DynamicWeirdness does get called.

Instead of overriding TryInvokeMember on DynamicWeirdness to return a different type, you can just create a new GetType() method on DynamicWeirdness.

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

For GetHashCode() and ToString(), you can override those members on DynamicWeirdness since they are marked as virtual.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文