2013-03-14 64 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>这不是很好!不幸的是,我现在要复制并粘贴并调整(泛型帮助我们避免的活动)。