2013-05-15 34 views
5

下面的代码抛出 “不明确的调用匹配” 在编译时:暧昧调用匹配混乱

class ABC{} 
class DEF{} 
class Program 
{ 
    static void Main(string[] args) 
    { 
     Debug.WriteLine(func(null)); 
    } 
    static string func(ABC abc) 
    { 
     return ""; 
    } 
    static string func(DEF def) 
    { 
     return ""; 
    } 
} 

但是,下面的代码编译并运行正常:

static void Main(string[] args) 
{ 
    Debug.WriteLine(func(null)); 
} 
static string func(int? abc) 
{ 
    return "function a"; 
} 
static string func(float? def) 
{ 
    return "function b"; 
} 

1.4.3

function a 

C#如何知道在第二个示例中选择哪个函数?

回答

12

当编译器对像这样的函数调用执行重载解析时,它会在候选中选择更好的函数成员(如果存在)。 更好的函数成员的定义包括C#语言规范的§7.5.3.2这样一段话:

7.5.3.2更好的函数成员

[...]

给出一个说法列表A具有一组参数表达式{E1,E2, ,...,EN}和两个可用的函数成员MP和MQ,其具有参数 类型{P1,P2,...,PN}和{Q1,Q2,...。 ...,QN},将MP定义为 是比MQ更好的函数成员,如果

  • 对于每个参数,从EX到QX的隐式转换 不大于从EX到PX的隐式转换更好,
  • 至少一个参数,从EX到PX的转换 比更好从EX转换到QX。

[...]

在这种情况下,MP是第一种方法(P1int?)和MQ是第二种方法(Q1float?)。因此,如果我们能够证明从nullint?的转换是更好的转换比容易转换为float?的行为很容易解释。

这是由规则§7.5.3.5确定:

7.5.3。5更好的转换目标

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

  • 从T1到T2的隐式转换存在,和从T2到T1的隐式转换存在

由于隐式转换从intfloat存在,但一个从floatint没有(reference),int更好的转换目标当选择这两种类型。

在您的例子中,我们处理这些类型的可空版本,但同样的逻辑也适用,关于非空的操作,因为

6.1.4隐可空转换

预定义的隐式转换值 类型也可以与这些类型的可为空形式一起使用。

+0

' 浮子F = 1; //工作 INT I = 1.0F; //不工作 ' 确定有意义 – Isaac

+0

奈斯利说明。 –