下面的代码有一个静态方法,Foo()
,调用实例方法,Bar()
:
public sealed class Example
{
int count;
public static void Foo( dynamic x )
{
Bar(x);
}
void Bar( dynamic x )
{
count++;
}
}
它编译时没有错误*,但在运行时生成运行时绑定器异常。正如预期的那样,删除这些方法的动态参数会导致编译器错误。
那么为什么拥有动态参数就可以编译代码呢? ReSharper 也不会将其显示为错误。
Edit 1:*在 Visual Studio 2008 中
Edit 2: added sealed
因为子类可能包含静态Bar(...)
方法。当不可能在运行时调用除实例方法之外的任何方法时,即使密封版本也会编译。
更新:以下答案写于2012年,在引入 C# 7.3 之前(2018 年 5 月). In C# 7.3 中的新增功能 https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-7-3, 这部分改进的过载候选者第 1 项,解释了重载解析规则如何更改,以便尽早丢弃非静态重载。因此,下面的答案(以及整个问题)现在大多只有历史意义!
(C# 7.3 之前的版本:)
由于某种原因,重载解析总是找到最佳匹配before检查静态与非静态。请尝试使用所有静态类型的代码:
class SillyStuff
{
static void SameName(object o) { }
void SameName(string s) { }
public static void Test()
{
SameName("Hi mom");
}
}
这不会编译,因为最好的重载是采用string
。但是,嘿,这是一个实例方法,所以编译器会抱怨(而不是采用第二好的重载)。
添加:所以我认为的解释dynamic
原始问题的例子是,为了保持一致,当类型是动态的时,我们也first找到最佳重载(仅检查参数数量和参数类型等,而不是静态与非静态),并且仅then检查静电。但这意味着静态检查必须等到运行时。因此观察到的行为。
后期添加:可以推断出他们为什么选择做这种有趣的顺序的一些背景埃里克·利珀特 (Eric Lippert) 的这篇博文 http://blogs.msdn.com/b/ericlippert/archive/2009/07/06/color-color.aspx.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)