2013-04-10 53 views
10

欲自定義對象的數組傳遞給一個函數像String.Join其具有以下特徵:傳遞數組函數,採用任一params對象[]或IEnumerable的<T>

  • public static string Join(string separator, params Object[] values)
  • public static string Join(string separator, IEnumerable<T> values)

如果我這樣調用該函數:

var arr = new MyClass[]{ new MyClass(), new MyClass() }; 
string text = string.Join("\n", arr); 

我得到一個編譯錯誤:

The call is ambiguous between the following methods or properties: 'string.Join(string, params object[])' and 'string.Join(string, System.Collections.Generic.IEnumerable)'

我可以用IEnumerable<T>功能解決歧義:

var arr = new MyClass[]{ new MyClass(), new MyClass() }; 
string text = string.Join<MyClass>("\n", arr); 

但我可以調用params object[]功能?在性能嚴重的情況下,最好直接訪問數組,而不是通過枚舉器訪問數組。

我使用C#4.0,如果這有什麼區別。

回答

17

如果您通過object[]作爲第二個參數,編譯器應該選擇object[]重載,因爲它完全匹配。在您(在這種情況下MyClass[])一個不同類型的數組的情況下,只需數組轉換爲object[]

string.Join("\n", (object[])arr); 

你實際上並沒有改變類型的任何物體或在運行時進行任何轉換,你」僅向編譯器提供有關使用哪個超載的提示。

關於您對性能的評論,如果性能非常關鍵,不要忘記對這兩個選項進行基準測試。不要以爲比別人快。 (且始終配置您的整個應用程序 - 這可能是任何瓶頸將是在其他地方。)

3

如果您改變arr變量的類型object[]你會調用其他重載:

object[] arr = new MyClass[] { new MyClass(), new MyClass() }; 
string text = string.Join("\n", arr); 

您還可以明確地將其轉換爲object[]:string.Join(「\ n」,(object [])arr);

0

可以調用其他重載這樣的(這是param使用什麼) -

string text = string.Join("\n", new MyClass(), new MyClass()); 
0

你的代碼最簡單的變化將是從去:

var arr = new MyClass[]{ new MyClass(), new MyClass() }; 
    string text = string.Join("\n", arr); 

要:

var arr = new object[]{ new MyClass(), new MyClass() }; 
    string text = string.Join("\n", arr); 

如前所述,鑄造也可以:

var arr = new MyClass[]{ new MyClass(), new MyClass() }; 
    string text = string.Join("\n", (object[])arr); 

要了解有關此主題的更多信息,請致電C# overload resolution

重載解析本身是一個有趣的主題,但我還沒有發現它是性能問題的瓶頸。

+0

正如我在我的問題中提到的,我想將數組傳遞給我自己的函數(而不是String.Join,但具有類似的方法簽名)的適當實現。這裏的性能差異是由於我的函數的不同實現。一些操作,比如獲取集合中的元素數量,使用數組而不是「IEnumerable 」更快。 – bouvierr 2013-04-10 21:22:46

+0

在IEnumerable是數組的情況下,Count()擴展方法使用.Length屬性,但那不是你的觀點。如果性能差異至關重要,您可能需要考慮爲成員使用不同的名稱,而不要依賴重載分辨率。因此,你不必強制編譯時類型來獲得你正在尋找的語義。 – Doug 2013-04-12 17:49:16

0

如果您使用的是IEnumerable可以使用ToArray()方法<object>泛型重載:

var allFoos = foo.GetAllFoos().ToArray<object>(); 
string s = string.Join(", ", allFoos); 

看起來臃腫少更易讀我。

相關問題