1、C#泛型
泛型是一种通用的数据类型,可以存储任何类型的数据,程序中使用泛型减少过程中复杂的装箱与拆箱操作,提高程序效率。
为什么选择泛型
实际开发中:某写功能实现方式相似仅参数类型不同,拷贝修改数据类型是能完成功能,可项目代码重复冗余。我们会想到定义Object类型处理,可曾想到操作反复的拆装与装箱带来的系统开销,影响效率。此时泛型就很好解决该问题了。看范例理解。
一、泛型方法
示范1.1:简单多个相似方法功能
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { public class 泛型1 { public static void Main(string[] args) { Print pr = new Print(); pr.IntData(1); pr.StrData("字符串"); pr.TimeDate(DateTime.Now); Console.ReadKey(); } } public class Print { public void IntData(int prams) { Console.WriteLine("参数类型是:{0}型", prams.GetType().Name); } public void StrData(string prams) { Console.WriteLine("参数类型是:{0}型", prams.GetType().Name); } public void TimeDate(DateTime prams) { Console.WriteLine("参数类型是:{0}型", prams.GetType().Name); } } }
输出:
认真观察,上面的三个方法分别输出参数类型,方法除了参数类型不同以外,实现的功能及代码基本一致!其实我们解决第一个参数就可以。可以使用基类型Object定义参数类型。
示范1.2:Object定义类型
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { public class 泛型1 { public static void Main(string[] args) { Print pr = new Print(); pr.objectData(1); pr.objectData("字符串"); pr.objectData(DateTime.Now); Console.ReadKey(); } } public class Print { public void objectData(object prams) { Console.WriteLine("参数类型是:{0}型", prams.GetType().Name); } } }
输出:
这样调整功能实现了,可如果objectData方法很多业务理解,就需要拆箱等操作。下面就示范泛型实现。
示范1.3:泛型方法
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { public class 泛型1 { public static void Main(string[] args) { Print pr = new Print(); pr.objectData<int>(1); //可以给<指定类型> pr.objectData(1); //<T>可以省略,自动根据参数推算 pr.objectData("字符串"); pr.objectData(DateTime.Now); Console.ReadKey(); } } public class Print { public void objectData<T>(T prams) { Console.WriteLine("参数类型是:{0}型", prams.GetType().Name); } } }
输出:
二、泛型类
声明泛型类语法格式:
修饰符 Class 类名<类型参表> { 类体 }
范例2.1:泛型类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { public class 泛型1 { public static void Main(string[] args) { Print<string> pr = new Print<string>("字符串"); pr.objectData(); Print2<int> pr1 = new Print2<int>(); pr1.objectData(1); Console.ReadKey(); } } public class Print<T> { private T data; public Print(T Data) { data = Data; } public void objectData() { Console.WriteLine("参数类型是:{0}型", data.GetType().Name); } } public class Print2<T> { public void objectData(T t) { Console.WriteLine("参数类型是:{0}型", t.GetType().Name); } } }
输出:
三、泛型接口
声明泛型接口语法格式:
//定义泛型接口 修饰符 Interface 接口名<类型形参表> { 接口体 } //泛型类实现泛型接口 Class 类名<类型形参表>:基接口<类型形参表> { 类体 }
示范3.1:声明泛型接口
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { interface 泛型接口<T> { void GetDataType(T type); } }
示范3.2:泛型类实现泛型接口
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { public class 泛型1 { public static void Main(string[] args) { GetData<int> g1 = new GetData<int>(); g1.GetDataType(5); GetData<string> g2 = new GetData<string>(); g2.GetDataType("泛型接口"); Console.ReadKey(); } } public class GetData<T> : 泛型接口<T> { public void GetDataType(T t) { Console.WriteLine("参数类型是:{0}型,值是:{1}", t.GetType().Name,t); } } }
输出:
四、泛型委托
示范4.1:泛型委托声明
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { public delegate void Mydelegate<T>(T t); public class 泛型委托<T> { public void GetDateType(T t) { Console.WriteLine("参数类型是:{0}型,值是:{1}", t.GetType().Name,t); } } }
示范4.2:泛型委托调用
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { public class 泛型1 { public static void Main(string[] args) { 泛型委托<int> obj = new 泛型委托<int>(); Mydelegate<int> de = obj.GetDateType; de(6); 泛型委托<string> obj1 = new 泛型委托<string>(); Mydelegate<string> de1 = obj1.GetDateType; de1("泛型委托"); Console.ReadKey(); } } }
输出:
五、使用泛型约束
定义泛型类时,可以限制在实例化类客户端代码的参数,当客户代码使用了被约束类型进行实例操作时出现编译错误,使用关键字 Where来实现
约束 | 说明 |
---|---|
T:struct |
类型参数必须是值类型。可以指定除 Nullable 以外的任何值类型。 |
T:class |
类型参数必须是引用类型,包括任何类、接口、委托或数组类型。 |
T:new() |
类型参数必须具有无参数的公共构造函数。当与其他约束一起使用时,new() 约束必须最后指定。 |
T:<基类名> |
类型参数必须是指定的基类或派生自指定的基类。 |
T:<接口名称> |
类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束。约束接口也可以是泛型的。 |
T:U |
为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。这称为裸类型约束. |