Mik*_*ott 109 c# compiler-errors dynamic visual-studio-2008
以下代码有一个静态方法Foo(),调用实例方法,Bar():
public sealed class Example
{
int count;
public static void Foo( dynamic x )
{
Bar(x);
}
void Bar( dynamic x )
{
count++;
}
}
Run Code Online (Sandbox Code Playgroud)
它编译时没有错误*但在运行时生成运行时绑定程序异常.正如预期的那样,删除这些方法的动态参数会导致编译器错误.
那么为什么有一个动态参数允许编译代码?ReSharper也没有将其显示为错误.
在Visual Studio 2008中编辑1:*
编辑2:添加,sealed因为子类可能包含静态Bar(...)方法.即使是密封版本也可以在运行时调用除实例方法之外的任何方法时进行编译.
Jep*_*sen 71
出于某种原因,在检查静态与非静态之前,重载决策始终找到最佳匹配.请尝试使用所有静态类型的代码:
class SillyStuff
{
static void SameName(object o) { }
void SameName(string s) { }
public static void Test()
{
SameName("Hi mom");
}
}
Run Code Online (Sandbox Code Playgroud)
这将无法编译,因为最好的重载是采取a string.但是,嘿,这是一个实例方法,所以编译器抱怨(而不是采取第二好的重载).
另外:所以我认为对dynamic原始问题的例子的解释是,为了保持一致,当类型是动态的时,我们也首先找到最佳的过载(仅检查参数号和参数类型等,而不是静态与非静态) -static),只有然后检查是否有静电.但这意味着静态检查必须等到运行时.因此观察到的行为.
后期补充:有关他们选择做这个有趣订单的原因的一些背景可以从Eric Lippert的博客文章中推断出来.
Mar*_*ell 30
Foo的参数"x"是动态的,这意味着Bar(x)是一个动态表达式.
Example完全可以使用以下方法:
static Bar(SomeType obj)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,将解析正确的方法,因此语句Bar(x)完全有效.存在实例方法Bar(x)的事实是无关紧要的,甚至没有考虑:根据定义,由于Bar(x)是动态表达式,我们将延迟解析为运行时.
"动态"表达式将在运行时绑定,因此如果使用正确的签名或实例方法定义静态方法,编译器将不会检查它.
"右"方法将在运行时确定.编译器无法知道运行时是否存在有效方法.
"dynamic"关键字是为动态和脚本语言定义的,其中可以随时定义Method,即使在运行时也是如此.疯狂的事情
这里有一个处理整数但没有字符串的示例,因为该方法在实例上.
class Program {
static void Main(string[] args) {
Example.Foo(1234);
Example.Foo("1234");
}
}
public class Example {
int count;
public static void Foo(dynamic x) {
Bar(x);
}
public static void Bar(int a) {
Console.WriteLine(a);
}
void Bar(dynamic x) {
count++;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以添加一个方法来处理无法处理的所有"错误"调用
public class Example {
int count;
public static void Foo(dynamic x) {
Bar(x);
}
public static void Bar<T>(T a) {
Console.WriteLine("Error handling:" + a);
}
public static void Bar(int a) {
Console.WriteLine(a);
}
void Bar(dynamic x) {
count++;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2639 次 |
| 最近记录: |