2013-03-14 46 views
31

今天,我在C#.NET 4.5中遇到了美麗的Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult>代表。我假設16是一個任意停止的地方(哪些方法有16個以上的參數?)但它讓我思考:是否可以在C#中指定一個泛型類型可以有任意數量的類型參數?,方法的params關鍵字允許方法的任意數量的參數。事情是這樣的:在C#中對通用參數使用「params」關鍵字

public class MyInfiniteGenericType<params T[]> { ... } 

所在班級裏面然後你可以通過它們計數或以相同的方式,params允許方法中使用T[index]訪問類型參數。

我從來沒有用過這個人,但Func代表將是一個完美的地方使用它。將不需要16種不同類型的Func!

所以我的問題是,這可以在C#中以任何方式完成,並且如果不是這是一個愚蠢的想法

+0

在SO上的其他地方討論:http://stackoverflow.com/a/4046525/63225 – sblom 2013-03-14 18:22:24

回答

29

是否有可能在C#中指定泛型可以有任意數量的類型參數?

不,C#沒有類似的東西我害怕。

基本上Func<T>Func<T1, T2>就CLR而言是完全不相關的類型,並且沒有像params那樣指定多個類型參數。

至於它的效用:我可以看到它可能有用的情況,但我懷疑它們非常罕見,意味着該功能不會超出「收益/成本」閾值。 (請注意,它幾乎肯定需要CLR更改。)

+2

今天我遇到了這種情況,並期待看看是否有可能。我不相信類似的東西應該省略,因爲成本/收益。我的意思是16種泛型類型的方法很醜陋...我敢打賭,幾乎沒有人使用它,所以花費在框架中的時間浪費了。 – 2014-03-31 01:59:16

+2

@rushonerok:將它放入框架的成本確實非常低,雖然它不會被*手動代碼使用,但它用於動態類型。更改語言以支持此功能請求的成本要高得多。 – 2014-03-31 05:45:25

2

不,不可能有任意數量的通用參數。這可能也是一個愚蠢的想法,因爲泛型類型參數在運行時沒有被解析,它們在編譯時被解析,所以像這樣迭代它們並不是一件明顯的事情。

你也許會認爲Tuple < ,,,,,,,,>可能是一個明顯的位置,但是當你用完泛型參數時,你會使最後一個元組成爲Tuple <, ,,,>爲其餘領域。

7

C++ 11具有您實質上正在談論的功能。他們稱之爲variadic templates

雖然C#泛型與C++模板不太相似,但會使構建完全相同的東西變得困難。

在C++的情況下,模板在編譯時展開爲使用的具體類型。在C#的情況下,類型說明完全在運行時發生。由此產生的IL將需要支持遇到的不同類型的數量。

1

不,這是做不到的。

它不像將它當作一個類型數組(它甚至不存在於C#中的概念)那樣簡單。考慮Func - 類型參數的數量必須與代理的Invoke方法的參數數量相同。但是程序員將如何表達類型參數和常規參數之間的這種關係?

但是,此功能在C++ 11中確實存在 - variadic templates。請注意,C++不允許使用數組語法來訪問各個類型參數 - 相反,函數通常會將第一個類型參數與其餘類型分開,並使用遞歸調用來解壓其餘的。

0

我只是發現自己好奇,看看是否有其他人有這個用法。我剛剛寫了一個通用作曲家來構建使用Castle Dynamic Proxy組合的mixins。

我建立作曲家支持兩個混入並正要上「複製和粘貼以及調整(的Bleh)」兩個混入作曲家繼續進入15個更多的變化高達17混合作曲家(類似於Func<T>通過Func<T1...T16, T> )。但後來我想,如果我可以定義Composer<TComposer, TIComposite, params[] TIMixin>這不是很好!不幸的是,我現在要複製並粘貼並調整(泛型幫助我們避免的活動)。