2013-12-17 71 views
6

真的很容易复制,输出是奇怪的;覆盖C#中的默认参数

预计输出为 “BBB BBB” 实际输出为 “AAA BBB”

有没有人有这种行为的任何MSDN解释?我找不到任何东西。

((a)new b()).test(); 
new b().test(); 


public class a 
{ 
    public virtual void test(string bob = "aaa ") 
    { 
     throw new NotImplementedException(); 
    } 
} 

public class b : a 
{ 
    public override void test(string bob = "bbb ") 
    { 
     HttpContext.Current.Response.Write(bob); 
    } 
} 
+0

是((a)(new b()))。test()给出你想要的结果吗? – rhughes

+4

根据* who *?的预期输出 – Jamiec

+0

我相信在重写方法时更改可选参数的默认值是无效的。这不会改变方法签名吗? –

回答

12

你为什么期望“bbb bbb”?

因为你是铸造实例a,要在第一次调用编译器的唯一信息是与"aaa"版本,所以该值就是用来

在没有投射的第二个版本中,编译器可以看到"bbb",所以那个值就是用什么

多态性影响哪个方法调用 - 但它不会影响传递的参数。从本质上讲,默认值是由编译器(在调用点)提供,所以你的代码实际上相当于:

((a)new b()).test("aaa"); 
new b().test("bbb"); 

其中"aaa""bbb"在编译时提供,通过检查的解决方法。

+3

因此,要重新强调,默认值是在编译时实现的,而不是运行时? –

+1

@BolucPapuccuoglu是;我已经添加了一些以强调这一点 –