2013-05-15 66 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

奈斯利說明。 –