我们在日常的开发任务中,经常遇到对不同的数据结构执行相同的操作,例如有一个方法传入的参数可能是字符串也可能是数字,这样的情况下,一般我们是直接传入一个object类型的参数,以便于可以实现这样的功能。例如以下代码。
private static void Show(object a)
{
Console.WriteLine(a.ToString());
}
这样的代码可是实现我们需要的功能,但是确定也很明显:1、只是传入一个object类型的参数,对于调用方来说,根本不知道应该传入一个什么类型的参数,很有可能以为参入参数的问题造成代码运行失败。2.object是一个引用类型,如果我们要处理的是一个值类型,那么就会产生装箱和拆箱的操作,频繁的装箱拆箱会对程序的性能造成极大的影响。在这样的需求下,C#2.0引入了泛型的概念,用于提供通用的功能以及编译时的类型安全。
一、泛型的定义
泛型的定义非常简单,<T>即可<>尖括号不能省略,T代表需要操作的具体类型,T不是固定的你可以使用任何有意义的符号代替。例如以下定义
private static void Show<TValue>(TValue a)
{
Console.WriteLine(a.ToString());//TValue代表需要操作的类型,需要注意的是TValue是类型而不是实例
}
泛型的定义可以放在方法上面,也可以放在整个类上面,放在方法上面那么只有当前方法是泛型方法,而直接放在类上面,则是把整个类全部定义为了泛型类,类内部的任何方法再使用此泛型的时候都可以不用再定义,如果需要定义多个泛型参数,则使用逗号隔开所有的参数,例如
private static void Show<TKey,TValue>(TValue a)
{
Console.WriteLine(a.ToString());
}
二、泛型方法的使用
定义了泛型方法就要去使用它,假设定义了如下的泛型方法
private static TValue Show<TValue>(TValue a)
{
Console.WriteLine(a.ToString());
return a;
}
那么应该怎么调用他呢?
Show<string>("此坑已满");
Show<int>(123);
在<>中使用需要操作的类型代替TValue这个符号
上面就是调用泛型方法的结果。
三、泛型约束
有时候我们需要我们的泛型参数满足一定的条件,例如我们需要T继承自IComparable接口,或者我们要求T不能是值类型,只能是引用类型这样的需求,该怎样满足呢?很简单,使用where即可,例如以下定义
//以下定义要求TValue必须是一个引用类型
private static TValue Show<TValue>(TValue a) where TValue:class
{
Console.WriteLine(a.ToString());
return a;
}
有了这样的定义,如果我们在调用泛型方法的时候把TValue定义为了一个值类型,那么VS的智能提示就会在编译时报错,这样就提供了编译时的类型安全。例如
如果是要求TValue要满足多个要求的话,则使用逗号分开即可
private static TValue Show<TValue>(TValue a) where TValue:class,IComparable,new ()
{
Console.WriteLine(a.ToString());
return a;
}
下面是常用的一些约束规则
其他更加详细的规则请参考MSDN
四、C#中常见的泛型
泛型可以用在方法,类型,接口,委托等等对象上面,在C#中有很多已经定义好的泛型供我们直接使用,例如List<T>,Dictionary<TKey,TValue>,Func<T1,T2>,Action<T>等等。他们的使用方法,请参考MSDN或者自行百度,谢谢!
原文:https://www.cnblogs.com/ckym/p/9942389.html