我从这里阅读了一篇有趣的文章/主题/讨论,并且遇到了以下问题:
编辑1 Eric Lippert推荐的其他问题
首先,您可能想阅读我在2009年关于该主题的文章。
在我看来,C 模板和C#泛型之间的主要区别在于,C 模板实际上 在构建 模板时就 完全重新编译了代码 。C ++方法的优缺点很多:
PRO:您可以有效地创建约束,例如“类型参数T必须具有加法运算符”;如果代码中包含彼此相加的两个T,则如果您使用不允许加法的类型参数构造模板,则模板将无法编译。
缺点:您可能会意外地创建未记录的约束,例如“类型参数T必须具有加法运算符”。
在C#中,您必须 说出 什么约束对用户有帮助,但是您只限于一小部分可能的约束:接口,基类,值与引用类型以及默认构造函数约束,仅此而已。
优点:两种不同结构的语义分析可能完全不同。如果您想要那样,那就太好了。
缺点:对于两种不同的结构,语义分析可能完全不同。如果您不希望那样,那就是一个等待发生的错误。
在C#中,无论构造类型多少次,语义分析都会进行 一次 ,因此需要使用 任何 满足约束的类型实参,而不仅仅是实际提供的类型实参。
PRO:您只为需要的构造生成代码。
缺点:您为所有使用的构造生成代码。
模板会导致代码生成变大。在C#中,只生成一次泛型类型的IL,然后在运行时抖动为程序使用的所有类型进行代码生成。这具有很小的性能成本,但是由于抖动实际上对于 所有引用类型参数 仅生成一次代码,因此可以在一定程度上缓解这种情况。因此,如果您有List<object>,List<string>则抖动代码仅生成一次,并用于两者。List<int>和List<short>由对比度即时编译的代码的两倍。
List<object>
List<string>
List<int>
List<short>
PRO:使用模板库时,您就可以在其中找到源代码。
缺点:要使用模板库,您必须具有源代码。
在C#中,泛型是一流的类型。如果将它们粘贴在库中,则可以在任何地方使用该库而不必附带源代码。
最后:
PRO:模板允许模板元编程。
缺点:新手很难理解模板元编程。
缺点:模板系统实际上不允许在通用系统中非常简单的某些类型拓扑。
例如,我想在C ++中很难做到这样:
class D<T> { class S { } D<D<T>.S> ds; }
在C#泛型中,没问题。在运行时,仅对所有引用类型参数构建 一次 该类型。
但是,在C++模板中,拥有后会发生什么D<int>?内部类型构造一个type的字段D<D<int>.S>,因此我们需要构造该类型。但是该类型构造了一个类型为D<D<D<int>.S>.S>…的字段,依此类推直至无穷大。
D<int>
D<D<int>.S>
D<D<D<int>.S>.S>