null动态变量和函数重载

时间:2015-05-07 05:50:24

标签: c# .net

示例代码:

private void DoSomething(object obj)
{
    MessageBox.Show("called object");
}

private void DoSomething(params object[] obj)
{
    MessageBox.Show("called object[]");
}


private void button1_Click(object sender, EventArgs e)
{
    decimal? amount = null;
    dynamic obj = amount;

    DoSomething(obj); 
}

单击按钮1时,消息"称为对象[]"被展示。在这个例子中,似乎首选带有object []参数的重载方法。有什么想法吗?我比任何事情都好奇。

(背景:这种行为在具有动态视图的Razor中引起了一些意想不到的结果 Formatting nullable decimal in RazorEngine)。

2 个答案:

答案 0 :(得分:18)

那是因为你可以将object[]投射到object而不是相反。 object[]更具体,因此在方法解决方面更受青睐。

  

7.5.3.2更好的职能成员

     

(...)

     

给定一个带有一组参数表达式{ E1, E2, ..., EN }的参数列表A和两个具有参数类型MPMQ的适用函数成员{ P1, P2, ..., PN }{ Q1, Q2, ..., QN }MP被定义为比MQ

更好的函数成员      
      
  • 对于每个参数,从EXQX的隐式转换并不比从EXPX的隐式转换更好,而
  •   
  • 对于至少一个参数,从EXPX的转换优于从EXQX的转换。
  •   

稍后在更好的转换目标上定义:

  

7.5.3.5更好的转化目标

     

鉴于两种不同类型T1T2T1是一个比T2更好的转换目标,如果至少满足下列条件之一:

     
      
  • 存在从T1T2的隐式转换,并且不存在从T2T1的隐式转换
  •   
     

(...)

在您的示例中,T1object[]T2object

答案 1 :(得分:7)

问题不是特定于“空动态变量”。即使您致电DoSomething(null),也会首选object[]重载。

这是因为即使null可以是objectobject[],也可以选择后者,因为它是更好转换目标,如{{3}所述}。

但是,如果您明确指定类型:

object x = null;
DoSomething(x);

然后将调用object重载,因为编译器已经知道空变量的类型。