C#--泛型

1.为了解决代码爆炸而出现,并且减少装拆箱操作而出现,提高代码的重用
1)定义算法,并不定义算法所要操作的数据类型,使用时在定义操作的数据类型
2)允许在class struct interface delegate中定义泛型
3)若定义了一个T,源代码使用数据类型的任何地方都可以使用T
4)泛型的定义都跟在命名后面 如 class class_nume {} void function_name(){} delegate void delegate_name(T a)

2.使用泛型带来的好处:
1)源代码的保护,使用泛型之后,可以不访问算法的源码,进行操作
2)类型安全,当封闭了一个泛型之后,如list intList 这个list只可以装int类型的变量,当然不介意麻烦的话,可以使用list 装
3)更清晰的代码,减少类型转换
4)更佳的性能,减少装拆箱的操作,list intList intList.add(n) x=intList[0] 时不发生这种操作。如果使用arraylist 就会发生装拆箱操作
虽然对于引用类型,并没有这种效果,可是清晰的类型,能提高代码的可读性
5)解决代码爆炸的问题

3.泛型的运用
1)类:多数运用于集合类中,事实上,集合类的管理都推荐使用泛型来管理,获取类型的安全,性能,可读。也可以使用在普通类中,不过问题是声明的时候要进行类型的封闭
2)接口:泛型接口被实现的时候,
可以选择封闭接口的类型(普通类),
class Student:IEnumrable{}
或者类型不指定的状态(对应泛型类)
class Student:IEnumerable{}
3)泛型委托
可以自己定义一个泛型的委托,再要实例一个委托用来接收一个方法时,进行类型的封闭
推荐使用官方定义的泛型委托Func(有返回值) Action(无返回值)
4)泛型方法
void function_name(T a){} 调用的时候进行类型的封闭。
不过大多是在泛型类中是正常的使用泛型如
class class_name{
void function_name(T a){}
}
该种使用不是泛型方法,是普通的方法,这是在使用数据类型的地方使用泛型变量

4.泛型的开放和封闭
泛型在声明的时候是开放的 如 class Student<Tkey,Tvalue> 这种类型,可是如果要进行实例化的时候必须对泛型进行类型封闭
Student<int,string> 是泛型的封闭类型

5.泛型的继承
普通的类 是可以派生出泛型类的
泛型类 派生子类的时候,必须先将类型关闭后才可以进行派生

6.泛型的同一性,泛型的类型推断
使用泛型的时候,代码会有很多 <> 影响代码的可读性
因此有些做法是先声明一个泛型类,然后在派生子类,进行类型封闭,这样在进行子类的变量声明的实例创建的时候就会减少<>的使用
这样带来的一个问题是class<封闭类型> 与 class_son的类型是不一样的,意味着如果一个方法是以子类为原型接收参数,那么class<封闭类型> 不符合
以基类为原型接收参数,class_son符合条件。
为了避免这种问题,可以在头部使用using XClass=Class<封闭类型> 然后声明变量和创建实例的时候就可以使用XClass来进行,并且typeof的结果是一致的
另外基于类型推断的机制,也可以减少<>的出现
如var oneValue=new Class<封闭类型>();
以及泛型方法在调用的时候,根据参数的类型 来推断类型参数,如
void Add(T a,T b){}
Add(1,2);这时编译器就会把T封闭成Int类型

7.泛型在接口和委托的使用过程要注意逆变与协变
in:标记为逆变量,允许变量类型转变为他的派生类型,只允许出现在输入的位置
out:标记位协变量,允许变量类型向基类型转变,只允许出现在输出的位置
delegate TResult Delegate_name<in T,out TResult>(T arg);
Delegate_name<Object,Object> fn2=null;这个委托可以指定任何的传入变量,和返回值类型的参数
第一个Object类型封闭的是输入参数,允许逆变,即接收任何Object类型的子类作为参数传入
第二个Object类型封闭的是返回参数,允许协变,允许任何类型返回值返回

8.泛型约束
放在声明的最后 “{” 的前面
常见的类型有
where T:new() 含有无参的构造函数
T:class 引用类型
T:struct 值类型
T:基类名 类以及他的派生
T:接口名 实现该接口的类型变量
T:U 为T提供的类型参数必须是U的约束一致

在编译泛型的代码的时候。编译器会确保代码适用于当前已有火将来可能定义的任何类型,如果不做泛型约束,泛型的作用将会大打折扣
class Class_name where T:new(){
T function_name(){
return new T();
}
}
是合法的,但是当把约束去掉之后,就会出现编译错误。因为不加约束的话,根本不可能知道这种类型变量是否有无参的构造函数
加了,那么将来进行封闭的类型变量就必须拥有无参的构造函数,所以上述的例子是合法的。

9.泛型需要注意的问题
泛型变量作为操作数使用在操作符的时候会出现大量的问题。所以不可能写一个能处理任何数值数据类型的算法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值