C#泛型
Copyright Notice: This article is an original work licensed under the CC 4.0 BY-NC-ND license.
If you wish to repost this article, please include the original source link and this copyright notice.
Source link: https://v2know.com/article/180
为什么会出现泛型?
1、避免代码重复
2、避免装箱和拆箱
3、保证类型安全
重复是指参数类型不同的的方法,为了统一参数类型,可以这么改动:
void Add(int x) 变成 void Add(T x)
对,就是把int改成T。
T被称为类型参数。
关于2和3条叙述的问题,是由于以前是用void(object x)来解决代码复用问题的。
因为用object类型存在装箱和拆箱,耗费资源,同时无法保证类型的正确性。
你传进去object是不会进行类型检查的,传string和传int都能传入。
典型应用:
List<int> list=new List<int>();
list.Add(100);
int num=list[0];
注意:
这里的<>里面的,可以是int、string,也可以是Model类。
经典使用例:
static void Swap<T>(ref T a,ref T b)
{
T temp=a;
a=b;
b=temp;
}
int x=5;
int y=10;
Swap(ref x,ref y);
泛型方法
在泛型类型里面的方法,除非也引入了类型参数(type parameters),否则是不会归为泛型方法的。
举个例子:
public class Stack<T>
{
int position;
T[] data=new T[100];
public void Push(T obj)=>data[position++]=obj;
public T pop()=>data[--position];
}
public T pop()不是泛型方法,因为这个T是class类型上的,不是这个方法引入的。
即:没使用<T>这样一个类型参数。
另外需要注意的是,
① 只有方法和类能引入类型参数
② 而属性、索引器、事件、字段、构造函数、操作符等都不可以声明类型参数
③ 但是他们可以使用他们所在泛型类型的类型参数,
比如:
public T this [int index]=>data[index];
关于声明类型参数
▢ 在声明class、struct、interface、delegate的时候可以引入类型参数(Typeparameters)。
▢ 其它的例如属性,就不可以引入类型参数,但是可以使用类型参数。
例如:
public struct Nullable<T>
{
public T Value{get;}
}
常见的类型声明:
class Dictionary<TKey,TValue>{ . . . }
Dictionary<int,string> myDic=new Dictionary<int,string>();
var myDic=new Dictionary<int,string>();
声明泛型类型:
▢ 泛型类型/泛型方法的名称可以被重载,条件是参数类型的个数不同:
class A{}
class A<T>{}
class A<T1,T2>{}
如上所示,这是3个互相独立的类。
▢ 按约定,泛型类型/泛型方法如果有一个类型参数,那么就叫T。
▢ 当使用多个类型参数的时候,每个类型参数都使用T作为前缀,随后跟着具有一个描述性的名字。
TYPEOF与未绑定的泛型类型
▢ 开放的泛型类型在编译后就变成了封闭的泛型类型。
▢ 但是如果作为Type对象,那么未绑定的泛型类型在运行时是可以存在的。(只能通过typeof操作符来实现)
举例:
class A<T>{}
class A<T1,T2>{}
. . .
Type a1=typeof(A<>);
Type a2=typeof(A<,>);
Type a3=typeof(A<int,int>);
class B<T>{void X(){Type t=typeof(T);}}
泛型的默认值
▢ 使用default关键字来获取泛型类型参数的默认值
static void Zap<T>(T[] array)
{
for(int i=0;i<array.Lengthl;i++)
array[i]=default(T);
}
default(T)的值是null或0,由引用类型还是值类型决定。
This article was last edited at