泛型
什么是泛型
C# 语言和公共语言运行时 (CLR) 在 2.0 版本中添加了泛型。泛型将类型参数的概念引入 .NET Framework,这样就可以设计具有相同特征的类和方法:在客户端代码声明并初始化这些类和方法之前,这些类和方法会延迟指定一个或多个类型(使用占位符~3:数字代表类型参数个数)
泛型有什么用
使用泛型类型可以最大限度地重用代码、保护类型安全性以及提高性能。泛型最常见的用途是创建集合类 List< int>。
可以创建:泛型接口、泛型类、泛型方法、泛型事件和泛型委托。
泛型的好处
- 增加类型的安全性
- 提高代码的重用
泛型的使用
问题:
自己编写一个入栈和出栈的通用类(任何数据类型都可以使用)类似与实现一个List的基本功能
public class MyList<T>
{
//数组和集合
T[] stack;
int size;
int stacPoint;//当前位置指针
public MyList(int length)
{
this.size = length;
stack = new T[size];
stacPoint = -1;
}
/// <summary>
/// 入栈
/// </summary>
/// <param name="item"></param>
public void Add(T item)
{
if (stacPoint>=size)
{
Console.WriteLine("集合已满");
}
else
{
stacPoint++;
stack[stacPoint] = item;
}
}
/// <summary>
/// 出栈
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public T Pop()
{
//提供的索引是存在元素的
T data = stack[stacPoint];
stacPoint--;
return data;
}
}
泛型类的规范:
public class 类名<T> {类成员....}
-
T:仅代表一个占位符,用T或者其他字母都行,只要符合C#命名规范都行,但是一般情况用T
-
T:表示一个通用的数据类型,在使用的时候用实际类型代替
-
T:泛型类可以在定义中可以包含多个任意类型参数,参数之间使用逗号隔开
例如
public class 类名<T1,T2,T3,....>{...}
各种类型参数都可以用作成员变量的类型、属性、方法等成员的返回类型,以及方法的参数类型
总结:以上泛型类的使用,增加了类型安全,实例化时int类型的约束下是不能添加string类型。无需拆箱操作
泛型类型的问题
无法为泛型类型赋值初始化
因为泛型类型可以理解为泛指所有的数据类型,而所有的数据类型可分为:值类型和引用类型,而且不同的数据类型支持的默认值是不一样的。
注意:
- 不能随便假设泛型类型是某种类型,这种类型也许没有构造方法,也许是私有的
- 解决方案使用default关键字,如果defalut中指定的类型最终是引用类型则默认是null,如果是值类型那就给值类型对应的默认值,数值就是0.结构类型要根据具体的成员类型确定是0还是null
泛型的约束
给泛型类或者泛型方法中的泛型参数,这个参数需要给一个类型范围
泛型约束有哪些
- where T : struct 类型参数必须是值类型。
- where T : class 类型参数必须是引用类型。 此约束还应用于任何类、接口、委托或数组类型。
- where T : unmanaged 类型参数不能是引用类型,并且任何嵌套级别均不能包含任何引用类型成员。
- where T : new() 类型参数必须具有公共无参数构造函数。
- where T : <基类名> 类型参数必须是指定的基类或派生自指定的基类
- where T : <接口名称> 类型参数必须是指定的接口或实现指定的接口
- where T : U 为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。
dynamic动态类型:根据程序的执行去动态的获取当前类型是什么类型,类型永远不固定,最终类型取决于本次使用该数据时,其数据的类型
var推断类型:根据第一次的初始值推断出该类型,一旦类型被推断出,则该数据的类型就确定好了,之后不可更改
泛型方法
//泛型方法
static T Add<T>(T a,T b) where T:struct
{
dynamic a1 = a;
dynamic b1 = b;
return a1 + b1;
}
dynamic和var和object 区别:
名 称 | 类 型 | 说 明 | 例子 |
---|---|---|---|
dynamic | 动态类型 | 根据程序的执行去动态的获取当前类型是什么类型,类型永远不固定,最终类型取决于本次使用该数据时,其数据的类型 | dynamic a = 100; a = “123”; |
var | 推断类型 | 根据第一次的初始值推断出该类型,一旦类型被推断出,则该数据的类型就确定好了,之后不可更改 | var i = 100;i=101; |
object | 对象类型 | 是所以类型的基类,故可以赋任何类型的值。 | object o = 100; o = “123”; |
委托技术的使用
委托是什么
- 委托是一种全新的面向对象语言特性,运行.NET平台上
- 基于委托,并发事件驱动程序变得非常简单
- 使用委托可以很大程度上简化多线程编程的难点
理解
- 委托可以看做一种数据类型,可以定义变量,但是他是一种特殊的变量
- 委托定义的变量能接收的数值只能使一个方法(函数),可以理解为委托就是方法的指针
委托的应用
主从窗体通信