当存在非静态、更适合的方法时,如何使用动态参数调用静态方法?

2023-12-21

灵感来自这个问题 https://stackoverflow.com/questions/12842712/why-does-the-c-sharp-compiler-not-fault-code-where-a-static-method-calls-an-inst我在 Mono 2.10.9 和 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- 我明确调用静态版本!

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

但是,更改非静态的参数类型Bar比如说,字符串,让一切都好起来。

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

也许这是 Mono DLR 问题?

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

或者,如果没有这样的规则,是否可以bug?这种行为可以通过某种方式避免吗?


其中的关键声明是“我知道我无法声明 static void Bar( int x ),因为存在非静态版本。”。使用dynamic关键字将重载决策推迟到运行时,但是当运行时出现时,它并不能免除您的规则。

当该过载解决方案最终发生时,DLR 会评估所有可用选项,然后选择最佳选项。在此解析时间之前,动态类型的参数的行为与对象类型非常相似(请参阅here http://msdn.microsoft.com/en-gb/library/dd264736.aspx)。因此,通常情况下,采用 int 的更具体的方法将是过载解决方案的获胜者,因此会选择采用动态/对象的方法。这意味着实例方法通常会获胜。 DLR 知道具有相同签名的两个方法不能因静态性而不同。在评估可用选项时,您期望它做的是说“啊哈!在这种情况下,static void Bar(dynamic x) 可以解释为 static void Bar(int x)”。然而,如果它确实这么说,那么就会违反关于不具有相同的静态和非静态方法的规则。它的内部选项列表将包含静态和非静态 Bar 方法,这两个方法都具有相同的签名。所以不能这么说。这就留下了唯一的其他选择,它恰好是实例方法。这在这种情况下没有用,因此 DLR 会抛出 RuntimeBinderException。如果将实例 Bar 的参数更改为 int 以外的参数,则方法签名不会冲突,因此 DLR 可以将静态动态 Bar 解释为采用 int 并选择该重载。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当存在非静态、更适合的方法时,如何使用动态参数调用静态方法? 的相关文章

随机推荐