C++的泛型是基于模板(template)技术的。模板本身并不作为独立的编译单元,而是在编译时绑定实际参数类型进行模板实例化,类似与C语言的宏展开,在运行时并不存在独立的模板类型。模板对泛型参数的约束是基于操作的语法特征的,属于一种静态的duck typing机制,十分灵活。
下面的代码定义了一个泛型Add函数,它对泛型参数T的要求只是支持+运算,并不要求T是某个类的子类,或是实现了某个接口。int, double, std::string等支持+运算符的类型都可以成功匹配T。
//C++
template<typename T>
T Add(const T& t1, const T& t2) {
return t1 + t2;
}
int main() {
int i = Add(1, 2);
double d = Add(1.1, 2.2);
std::string s = Add(std::string("abc"), std::string("def"));
std::cout << i << " " << d << " " << s << std::endl;
return 0;
}
输出:
>>3 3.3 abcdef
而类似的代码在C#中却无法编译通过:
这是由于C#采用基于reification的泛型机制,泛型类会单独编译,并且在运行时存在;因此,C#对于泛型参数的要求更加严格,只能通过where关键字表达基于继承关系的约束,无法通过duck typing的方式表达类型约束。与模板相比,这种机制的好处在于可以更好的支持反射和元编程,但其缺点是泛型的表达能力不如模板。幸好C#4.0中引入了动态类型机制,我们可以通过动态类型来实现基于duck typing的泛型参数约束。
//C#
static class Calculator {
public static T Add<T>(T t1, T t2) {
dynamic d1 = t1;
dynamic d2 = t2;
return (T)(d1 + d2);
}
}
public static void Main(string[] args){
int i = Calculator.Add(1, 2);
double d = Calculator.Add(1.1, 2.2);
string s = Calculator.Add("abc", "def");
Console.WriteLine(i + " " + d + " " + s);
}
输出:
>>3 3.3 abcdef
除了运算符重载,对于普通的方法调用也是适用的。这种方法是一种动态duck typing的泛型参数约束机制,依赖于运行时的方法查找,与模板编译时的检查不同,它需要使用者保证传入的对象符合相应要求。
分享到:
相关推荐
### C# 泛型培训理论 + ...泛型是C#中一个强大的特性,它不仅提高了代码的可读性和可维护性,还增强了类型安全性并减少了代码重复。通过学习和应用泛型的概念和技术,开发者可以编写出更加高效、健壮的软件应用程序。
C# 泛型中的数据类型判定与转换 在 C# 中,泛型是非常重要的概念,它可以使得代码更加灵活和通用。然而,在使用泛型时,我们经常会遇到数据类型判定与转换的问题。本文将详细介绍 C# 泛型中的数据类型判定与转换,...
废话不多说了,直接给大家贴代码了,具体代码如下所示: public class Person { public string FirstName{set;get;} public string LastName{set;get;} public Person(){} public Person(string firstName, ...
C# 4.0是微软开发的面向对象的编程语言C#的重要版本更新,它引入了一系列新特性,旨在提升开发者的生产力和代码的灵活性。在这一版本中,C#开始更加紧密地与动态语言集成,同时也对现有特性进行了增强。 **动态类型...
本篇文章将深入探讨如何使用C#加载DLL,并通过反射来调用其中的公开方法、私有方法以及泛型方法。 首先,我们需要了解什么是DLL(Dynamic Link Library)。DLL是一种可重用的代码库,它包含了一系列可由多个程序...
1. **动态类型**(Dynamic Type):C# 4.0引入了动态类型`dynamic`,允许在运行时确定变量的类型。这使得与非C#环境(如IronPython或JavaScript)的交互变得更加灵活,无需显式地进行类型转换。 2. **可空值类型**...
4. **扩展方法**:C# 5.0中的扩展方法可以让开发者为现有类型添加新的方法,而无需继承或使用装饰器模式,增强了代码的可读性和灵活性。 5. **LINQ(Language Integrated Query)**:C# 5.0对LINQ进行了优化,提供...
最后,C# 7.0支持了多重返回值,通过`ValueTuple`,可以一次性返回多个结果,提高了代码的效率和表达力。 通过《C# 7.0 in a Nutshell》和《C# 5.0 in a Nutshell》这两本书,读者将能够深入理解C#语言的核心概念,...
11. **C#泛型** - **泛型基础**:讲解泛型的基本概念及其在C#中的实现。 - **泛型集合**:介绍C#中常用的泛型集合类型及其使用方法。 - **性能优势**:讨论泛型如何提高代码的可读性、可维护性和性能。 #### 四...
15. **C#版本更新**:从C# 1.0到最新的C# 11,每个新版本都引入了新的特性和改进,如C# 8.0的默认接口方法,C# 9.0的模式匹配增强等。 学习C#,你需要掌握以上基础知识,并通过实践加深理解。提供的压缩包文件"展现...
C# 4.0是其一个重要版本,引入了许多新特性,如动态类型、命名参数、可空引用类型等,增强了语言的灵活性和表达能力。 动态类型在C# 4.0中是一个重大改进,允许变量在运行时绑定到任何类型,这极大地简化了与动态...
此外,C# 5.0还引入了动态类型(`dynamic`),它允许在运行时确定变量的类型,增强了与动态语言如IronPython和IronRuby的互操作性。动态类型可以用于简化与COM对象交互或处理JSON等动态数据。 另一个显著的改进是...
使用C# 4.0的新特性,可以直接使用`dynamic`类型来调用这个方法,而不需要显式地使用`IUnknown`。 #### Relationship with Visual Basic 与Visual Basic的关系 C# 4.0的一些新特性,如`dynamic`类型和可选参数,也...
8. **动态类型**:C# 4.0引入了dynamic类型,允许在运行时动态绑定对象和方法,增强了语言的灵活性。 9. **特性(Attributes)**:C#中的特性是一种元数据,可以附着在程序元素上,为编译器、运行时或工具提供额外...
C#是一种广泛应用于软件开发,尤其是Windows平台和.NET框架下的编程语言。本教程集合了我工作和学习过程中积累的C#各种知识点,旨在帮助你深入理解和掌握C#的基础及高级特性。 1. **C#基础知识** - **变量与数据...
8. **泛型约束**:C# 3.0增强了泛型约束,如`where T : class`和`where T : struct`用于指定类型参数必须是引用类型或值类型。此外,还可以添加`new()`约束,确保类型参数有一个默认构造函数,或`where T : ...
- **动态类型**:C# 4.0引入了dynamic类型,允许我们在运行时确定对象类型,增强了语言的灵活性。 #### 六、本书内容概览 根据描述,本书《C#开发实例大全(基础卷)》主要围绕C#的基础知识展开,通过大量的实例来...
C#是由微软公司为.NET框架开发的一款面向对象的编程语言,它集成了许多现代编程特性,如强类型、垃圾回收、异常处理、泛型等,使得开发高效、可靠的软件变得更加便捷。 C#的基础知识包括: 1. **基本语法**:C#语言...
在对象模型和泛型方面,《C#4.0权威指南》会深入讲解接口(interface)、抽象类(abstract class)和枚举(enum),以及泛型类、接口和方法的使用。泛型可以提供类型安全和代码重用,是现代C#编程不可或缺的部分。 ...