C#泛型

| CSharp | 1k+ Reads

为什么会出现泛型?

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