null动态变量和函数重载

Moe*_*sko 18 .net c#

示例代码:

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); 
}
Run Code Online (Sandbox Code Playgroud)

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

(背景:这种行为在使用动态视图的Razor中导致了一些意想不到的结果 在RazorEngine中格式化可为空的十进制).

Mar*_*zek 18

那是因为你可以投object[]object,而不是周围的其他方式.object[]更具体,因此在方法解决方案中更受青睐.

7.5.3.2更好的功能成员

(......)

给定一个参数列表A与一组参数表达式的{ E1, E2, ..., EN }和两个适用函数成员MPMQ与参数类型{ P1, P2, ..., PN }{ Q1, Q2, ..., QN },MP被定义为是一个更好的功能部件比MQ如果

  • 为每个参数,从隐式转换EXQX距离比隐式转换不是更好EXPX,并
  • 对于至少一个参数,从EXto PX转换比从EXto 转换更好QX.

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

7.5.3.5更好的转换目标

给出了两种不同类型T1T2,T1是更好的转换目标比T2如果以下中的至少一个成立:

  • 从隐式转换T1T2存在,从没有隐式转换T2T1存在

(......)

在您的例子T1object[]T2object.


iml*_*esh 7

问题不是特定于"空动态变量".即使你打电话DoSomething(null),object[]过载也是首选.

这是因为即使null可以是object或者object[],后者也是首选,因为它是MarcinJuraszek所解释的更好的转换目标.

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

object x = null;
DoSomething(x);
Run Code Online (Sandbox Code Playgroud)

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