当非静态,更好拟合的方法存在时,如何使用动态参数调用静态方法? [英] How to invoke static method with dynamic argument when a non-static, better-fit method exists?

查看:158
本文介绍了当非静态,更好拟合的方法存在时,如何使用动态参数调用静态方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

灵感来自这个问题我在Mono 2.10.9和Visual Studio 2010上尝试了以下代码:

Inspired by this question I have tried a following code on Mono 2.10.9 and Visual Studio 2010:

public class Example
{
    public static void Main()
    {
        Foo(1);
    }

    public static void Foo( dynamic x )
    {
        Example.Bar(x);
    }

    static void Bar( dynamic x )
    {
        x++;
    }

    int count;
    void Bar( int x )
    {
        count++;
    }
}

如您所见, Foo 是静态的,所以它只能访问静态 Bar - 我明确地调用静态版本!

As you can see, Foo is static, so it can only access static Bar - and I explicitly invoke the static version!

我知道我将无法声明 static void Bar(int x)静态版本存在。

I know that I would not be able to declare static void Bar( int x ), because a non-static version exists.

但是,将非静态 Bar 的参数类型更改为,使一切都好起来。

However, changing the argument type of non-static Bar to, let's say, string, makes everything alright.

为什么?这里有什么规则?可以调用静态方法吗?

Why is that? What are the rules here? Is it possible to call the static method?

也许这是一个单声道DLR问题?

Maybe it's a Mono DLR issue?

编辑:为了澄清。我想知道什么规则将静态方法的显式调用(至少我认为是明确的)转换为非静态的调用?这显然是不可能的静态上下文。

For clarification. I would like to know what rules turn an explicit call to static method (at least I think it's explicit) into a call to a non-static one? This is obviously impossible from static context.

或者,如果没有这样的规则,它可以是一个错误?这个行为可以避免吗?

Or, if there are no such rules, can it be a bug? Can this behaviour be somehow avoided?

推荐答案

关键语句是我知道我将无法声明静态void Bar(int x),因为存在非静态版本。使用动态关键字将重载解析度延迟到运行时间,但是当运行时出现时,它不会免除您的规则。

The key statement there is that "I know that I would not be able to declare static void Bar( int x ), because a non-static version exists.". Using the dynamic keyword defers the overload resolution to run-time, but it doesn't exempt you from that rule when run-time comes along.

当该重载分辨率最终发生,DLR评估所有可用的选项,然后选择最好的选项。在此分辨率时间之前,动态类型的参数与类型对象非常相似(请参阅这里)。因此,通常采用int的更具体的方法将是超量级分辨率的获胜者,因此可以选择采用动态/对象的方法。这意味着实例方法通常会赢。 DLR知道具有相同签名的两个方法不能因静态而变化。在评估可用选项时,您所期待的是说aha!在这种情况下,静态空格(动态x)可以解释为静态无效条(int x)。但是,如果这样做,那么关于没有其他相同的静态和非静态方法的规则将被违反。内部的选项列表将包含静态和非静态的Bar方法,两者都具有相同的签名。所以不能这样说。这留下唯一的其他选项,恰好是一个实例方法。这在这种情况下是没有用的,所以DLR抛出一个RuntimeBinderException。如果将实例栏的参数更改为int以外的方法,则方法签名不会冲突,因此DLR可以将静态动态栏解释为采用int并选择该重载。

When that overload resolution finally occurs, the DLR evaluates all the options available and then chooses the best one. Until this resolution-time, parameters of dynamic type behave much like being of type object (see here). So normally the more specific method that takes an int would be the winner in the overoad resolution and thus be chosen over the one that takes a dynamic/object. This means that the instance method would normally win. The DLR knows that two methods with the same signature cannot vary by staticness. When evaluating the options available, what you are expecting it to do is say "aha! In this case, static void Bar(dynamic x) can be interpreted as static void Bar(int x)". However, if it did say that, then the rule about not having otherwise identical static and non-static methods would be violated. It's internal list of options would contain the static and non-static Bar methods, both of which would have the same signature. So it can't say that. This leaves the only other option, which happens to be an instance method. This is no use in the circumstances so the DLR throws a RuntimeBinderException. If you change the parameter of the instance Bar to something other than an int, then the method signatures do not clash, so the DLR can interpret the static dynamic Bar as taking an int and select that overload instead.

这篇关于当非静态,更好拟合的方法存在时,如何使用动态参数调用静态方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆