C# 泛型
C# 泛型(Generic)
泛型(Generic) 允许延迟编写类或方法中的编程元素的数据类型的规范,直到实际在程序中使用它的时候。换句话说,泛型允许编写一个可以与任何数据类型一起工作的类或方法。
可以通过数据类型的替代参数编写类或方法的规范。当编译器遇到类的构造函数或方法的函数调用时,它会生成代码来处理指定的数据类型。
public static void run() { Val<string>.setVal("233"); Console.WriteLine(Val<string>.getVal()); Val<int>.setVal(114514); Console.WriteLine(Val<string>.getVal()); Console.WriteLine(Val<int>.getVal()); } class Val<T> { private static T value; public static T getVal() { return value; } public static void setVal(T v) { value = v; } }
233 233 114514
泛型(Generic)的特性
使用泛型是一种增强程序功能的技术,具体表现在以下几个方面:
- 它有助于最大限度地重用代码、保护类型的安全以及提高性能。
- 可以创建泛型集合类。.NET 框架类库在 System.Collections.Generic 命名空间中包含了一些新的泛型集合类。可以使用这些泛型集合类来替代 System.Collections 中的集合类。
- 可以创建自己的泛型接口、泛型类、泛型方法、泛型事件和泛型委托。
- 可以对泛型类进行约束以访问特定数据类型的方法。
- 关于泛型数据类型中使用的类型的信息可在运行时通过使用反射获取。
泛型(Generic)方法
public static void run() { string va = "114514"; string vb = "anything"; Console.WriteLine($"va:{vb},vb:{va}"); GenericMethod.exchange<string>(ref va,ref vb); Console.WriteLine($"va:{vb},vb:{va}"); } class GenericMethod { public static void exchange<T>(ref T val1,ref T val2) { T temp = val1; val1 = val2; val2 = temp; } }
在声明泛型方法/泛型类的时候,可以给泛型加上一定的约束来满足我们特定的一些条件。
比如:
public class Val<T> where T:new() { }
泛型限定条件:
- T:结构(类型参数必须是值类型。可以指定除 Nullable 以外的任何值类型)
- T:类 (类型参数必须是引用类型,包括任何类、接口、委托或数组类型)
- T:new() (类型参数必须具有无参数的公共构造函数。当与其他约束一起使用时new() 约束必须最后指定)
- T:<基类名> 类型参数必须是指定的基类或派生自指定的基类
- T:<接口名称> 类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束。约束接口也可以是泛型的。
- T:U
泛型(Generic)委托
可以通过类型参数定义泛型委托。例如:
delegate T NumberChanger<T>(T n);
delegate T ValChanger<T>(T n); public static void run() { ValChanger<int> vc = new ValChanger<int>(setInt); Console.WriteLine(vc(10)); ValChanger<string> vs = new ValChanger<string>(setString); Console.WriteLine(vs("Hello World")); } public static string setString(string n) { return n +=" "+n ; } public static int setInt(int n) { return n * 2; }
20 Hello World Hello World
‘’