2012-11-20 66 views
4

我正在編寫一個序列化程序,我希望廣泛使用方法重載,以便序列化來自IEnumerable<T>IDictionary<K,V>等的類型的對象。在解決C#中的方法重載時,優先級的規則是什麼?

我還打算使用dynamic關鍵字來讓CLR根據要序列化的對象的運行時類型選擇正確的過載。

看一看這個代碼片段:

void Serialize<TKey, TValue>(IDictionary<TKey, TValue> dictionary) 
{ 
    Console.WriteLine("IDictionary<TKey, TValue>"); 
} 

void Serialize<TKey, TValue>(IEnumerable<KeyValuePair<TKey, TValue>> items) 
{ 
    Console.WriteLine("IEnumerable<KeyValuePair<TKey, TValue>>"); 
} 

void Serialize<T>(IEnumerable<T> items) 
{ 
    Console.WriteLine("IEnumerable<T>"); 
} 

而且我想這樣做:

void CallSerialize(object obj) 
{ 
    Serialize(obj as dynamic); //let the CLR resolve it at runtime. 
} 

現在基於運行時類型的obj,正確的過載將被調用。例如,

//Test code 
CallSerialize(new List<int>()); //prints IEnumerable<T> 

在這種情況下,調用第三個重載並且基本原理非常簡單:這只是可行的選項。

但是,如果我這樣做:

CallSerialize(new Dictionary<int,int>()); //prints IDictionary<TKey, TValue> 

它調用第一個重載。我不完全明白這一點。當所有三種過載都是可行的選項時,爲什麼它會解決第一次過載?實際上,如果我刪除第一個,則調用第二個重載,如果我刪除第一個和第二個重載,則調用第三個重載。

解決方法重載時優先級的規則是什麼?

+0

大部分繼承類型? 'IDictionary '比'IEnumerable >'派生得更多,它比'IEnumerable '派生得更多。這只是一個猜測,但它似乎是邏輯(至少對我來說)。 – Paciv

+0

您不需要使用'dynamic'來讓編譯器重載解析。實際上,'dynamic'跳過編譯時間解析並在運行時執行。 – Rik

回答

6

解決方法重載的規則將嘗試選擇最具體類型匹配的方法頭。 Here你可以閱讀更多關於超載分辨率和here我認爲你的情況。

從MSDN:

鑑於與一組參數類型{A1,A2,...,AN}和兩個適用函數成員MP和MQ與參數類型{P1,P2的參數列表A ,...,PN}和{Q1,Q2,...,QN},MP被定義爲比MQ更好的功能部件,如果

  • 對於每個參數,從AX到PX的隱式轉換並不遜於從AX到QX的隱式轉換,並且

  • 對於至少一個參數,從AX到PX的轉換優於從> AX到QX的轉換。

當執行該評價中,如果MP或MQ是適用在其膨脹形式,則PX或QX是指在參數列表中的擴展形式的參數。

+1

這些鏈接有點過時。您可以從http://go.microsoft.com/fwlink/?LinkId=199552獲取最新規格。尋找7.5.3節。 – fsimonazzi