2015-05-07 27 views
18

示例代碼:空動態變量和函數重載

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); 
} 

當點擊按鈕1,「[]調用的對象」時顯示的消息。在這個例子中,似乎使用object []參數的重載方法是首選。任何想法爲什麼?我只是好奇而已。

(背景:這種行爲在動態視圖 Formatting nullable decimal in RazorEngine中引起了剃刀的一些意外結果)。

回答

18

這是因爲您可以將object[]投射到object而不是其他方式。 object[]更具體,因此在方法解析中受到青睞。

7.5.3.2更好功能構件

(...)

鑑於與一組參數表達式的{ E1, E2, ..., EN }和兩個適用函數成員MPMQ與參數類型的參數列表A { P1, P2, ..., PN }{ Q1, Q2, ..., QN },MP定義爲比MQ更好的功能成員,如果

  • 對於每個參數,隱式轉換從EXQX不大於從EXPX的隱式轉換更好,
  • 至少一個參數,從EXPX的轉換比從EX到轉換更好QX

,後來被定義的更好的轉換目標:給定兩個不同類型的T1T2

7.5.3.5更好的轉換目標

T1是一個更好的如果以下至少一項成立,則轉換目標爲T2

  • T1T2的隱式轉換存在,並沒有隱式轉換從T2T1存在

(...)

在您的例子T1object[]T2object

+0

對於任何人想知道的,這個答案中引用的書是:https://books.google.co.in/books?id=s-IH_x6ytuQC – imlokesh

+1

@imlokesh你錯了。我引用了C#規範,而不是一本書。 – MarcinJuraszek

+0

我的不好,我搜索了你引用的確切文字,這是第一個結果。 :) – imlokesh

7

該問題不是特定於「空動態變量」。即使您撥打DoSomething(null),也會優先使用object[]過載。

這是因爲即使空可以是objectobject[],後者是優選的,由於它是一個更好的轉換目標通過MarcinJuraszek解釋的那樣。

但是,如果你明確地指定類型是這樣的:

object x = null; 
DoSomething(x); 

然後object超載將被調用,因爲編譯器已經知道空變量的類型。