2013-02-15 35 views
9
public enum EnumTest 
{ 
    EnumEntry 
} 

public class TestClass 
{ 
    public string FunctionMember(string s, EnumTest t = EnumTest.EnumEntry) 
    { 
     return "Normal"; 
    } 

    public string FunctionMember<T>(T t) 
    { 
     return "Generic"; 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     TestClass t = new TestClass(); 

     Console.WriteLine(t.FunctionMember("a")); 
    } 
} 

這將打印「通用」。刪除, EnumTest t = EnumTest.EnumEntry使其打印「正常」。爲什麼通用函數成員選擇的是非泛型成員?

然而標準似乎是很清楚,從14.4.2.2更好的函數成員第一鑑別要應用是:

  • 如果MP和MQ的一個不通用,但其他是通用的,那麼非通用更好。

我錯過了什麼或編譯器錯誤?

+0

你在看C#4.0規範嗎?我懷疑你正在查看一個較舊的規範,它沒有提及可選參數,因爲那些只是在C#4.0中引入的。 – CodesInChaos 2013-02-15 13:08:19

+0

我相信你的方法有不同的簽名。你是否嘗試過,例如傳遞int或其他東西? – 2013-02-15 13:09:22

+0

@Codes:我沒有,但4.0規範說了同樣的事情,只是它在7.5.3.2。 – 2013-02-15 13:11:30

回答

8

你錯過了什麼。這是以下內容:

您使用一個參數調用該方法。只有一種方法具有一個參數,即通用參數。所以這就是選擇的那個。

只有當它沒有找到匹配的方法時,它纔會查看其他具有可選參數的方法。

參考文獻:

  1. C# 4.0 Specification,在21.4最後一段:

    作爲決勝規則,對於這其中明確給出的所有參數優於一個爲函數成員默認值是用來代替明確的參數。

  2. MSDN,標題爲「超載決議」,最後一個項目符號點:

    如果兩個候選人被判斷爲一樣好,偏好去不有哪些參數是可選參數的候選在通話中省略。這是因爲參數較少的候選人在重載分辨率方面普遍偏好的結果。

  3. The C# Language Specification,章節 「7.5.3.2更好函數成員」:

    • 擴展形式:

      對於每個候選功能的部件以下面的方式構造的參數列表如果函數成員僅適用於擴展形式,則使用該函數。

    • 沒有對應參數可選參數從參數列表移除

    它繼續這樣的:

    鑑於與一組參數表達式的參數列表A {ë ,E ,...,E Ñ}和兩個適用函數成員MP和MQ與參數類型{P ,P ,...,P Ñ}和{Q ,Q 。 ..,Q ñ} [...]

    此時與可選的參數的方法是已經退出遊戲。 N是1,但該方法有兩個參數。

+0

你能引用規範來支持它嗎?即必須替代可選參數的默認值比不得不使用通用方法更糟糕? – CodesInChaos 2013-02-15 13:13:22

+0

@CodesInChaos:請參閱更新。 – 2013-02-15 13:13:45

+0

oO爲什麼他們將4.0的功能放入單獨的草稿文檔中?正常的C#4。0規範不包含這些章節。 – CodesInChaos 2013-02-15 13:20:17

3

docs說:

如果兩個候選人被判斷爲一樣好,偏好去不有哪些參數是在調用省略可選參數的候選人。這是因爲參數較少的候選人在重載分辨率方面普遍偏好的結果。

換句話說,沒有任何可選參數的方法將是優選的。

1

使用方法參數的默認值,重載分辨率得到了擴展。

從概念上說,將運行pre v4中的方法重載分辨率。如果發現匹配匹配將被使用。 (概念,因爲這不是它是如何工作的描述,但你能怎麼想的吧)

你的情況,發現只有一個比賽是你的泛型方法

如果沒有找到匹配它的外觀對於具有部分匹配的方法以及可以使用默認值完成匹配的方法。在你的情況下,你會發現在這次運行中沒有一個通用的方法,但是由於已經找到了一個匹配,所以分辨率從未達到這個目標。

刪除第二個參數時,最終會出現泛型和非泛型匹配的情況。你選擇非規範化的規則。

總而言之,一個好的經驗法則是將選擇最具體的可用方法。

匹配的非泛型方法比泛型更具體,因爲類型不能改變。 如果有兩個方法可用,但一個接受IFoo的參數,另一個接受Foo(實現IFoo),則具有默認參數的方法不如參數計數匹配參數計數(數字完全匹配)的方法更具體 。那麼在傳遞Foo對象作爲參數時將選擇後者,因爲它完全匹配Ie。更具體的

相關問題