C# 泛型
MSDN 章节内容
- 泛型介绍(C# 编程指南)
- 泛型的优点(C# 编程指南)
- 泛型类型参数(C# 编程指南)
- 类型参数的约束(C# 编程指南)
- 泛型类(C# 编程指南)
- 泛型接口(C# 编程指南)
- 泛型方法(C# 编程指南)
- 泛型委托(C# 编程指南)
- 泛型代码中的默认关键字(C# 编程指南)
- C++ 模板和 C# 泛型之间的区别(C# 编程指南)
- 泛型和反射(C# 编程指南)
- 运行库的泛型(C# 编程指南)
- .NET Framework 类库中的泛型(C# 编程指南)
- “泛型”示例 (C#)
泛型是 2.0 版 C# 语言和公共语言运行库 (CLR) 中的一个新功能。泛型将类型参数的概念引入 .NET Framework,类型参数使得设计如下类和方法成为可能:这些类和方法将一个或多个类型的指定推迟到客户端代码声明并实例化该类或方法的时候。例如,通过使用泛型类型参数 T,您可以编写其他客户端代码能够使用的单个类,而不致引入运行时强制转换或装箱操作的成本或风险,如下所示:
// Declare the generic class public class GenericList<T> { void Add(T input) { } } class TestGenericList { private class ExampleClass { } static void Main() { // Declare a list of type int GenericList<int> list1 = new GenericList<int>(); // Declare a list of type string GenericList<string> list2 = new GenericList<string>(); // Declare a list of type ExampleClass GenericList<ExampleClass> list3 = new GenericList<ExampleClass>(); } }
若要使用 GenericList<T>
,客户端代码必须通过指定尖括号中的类型参数来声明和实例化构造类型。此特定类的类型参数可以是编译器识别的任何类型。可以创建任意数目的构造类型实例,每个实例使用不同的类型参数,如上所示:
泛型概述
-
使用泛型类型可以最大限度地重用代码、保护类型的安全以及提高性能。
-
泛型最常见的用途是创建集合类。
-
.NET Framework 类库在 System.Collections.Generic 命名空间中包含几个新的泛型集合类。应尽可能地使用这些类来代替普通的类,如 System.Collections 命名空间中的 ArrayList。
-
您可以创建自己的泛型接口、泛型类、泛型方法、泛型事件和泛型委托。
-
可以对泛型类进行约束以访问特定数据类型的方法。
-
关于泛型数据类型中使用的类型的信息可在运行时通过反射获取
// The .NET Framework 2.0 way to create a list List<int> list1 = new List<int>(); // No boxing, no casting: list1.Add(3); // Compile-time error: // list1.Add("It is raining in Redmond.");
对于以上代码,与 ArrayList 相比,使用 List<T>
时添加的唯一语法是声明和实例化中的类型参数。虽然这稍微增加了些编码的复杂性,但好处是您可以创建一个比 ArrayList 更安全并且速度更快的列表,特别适用于列表项是值类型的情况。
类型参数命名准则
-
务必使用描述性名称命名泛型类型参数,除非单个字母名称完全可以让人了解它表示的含义,而描述性名称不会有更多的意义。
public interface ISessionChannel<TSession> { /*...*/ } public delegate TOutput Converter<TInput, TOutput>(TInput from); public class List<T> { /*...*/ }
-
考虑使用 T 作为具有单个字母类型参数的类型的类型参数名。
public int IComparer<T>() { return 0; } public delegate bool Predicate<T>(T item); public struct Nullable<T> where T : struct { /*...*/ }
-
务必将“T”作为描述性类型参数名的前缀。
public interface ISessionChannel<TSession> { TSession Session { get; } }
-
考虑在参数名中指示对此类型参数的约束。例如,可以将带有
ISession
约束的参数命名为TSession
。
泛型类
泛型类封装不是特定于具体数据类型的操作。泛型类最常用于集合,如链接列表、哈希表、堆栈、队列、树等,其中,像从集合中添加和移除项这样的操作都以大体上相同的方式执行,与所存储数据的类型无关。