C#学习笔记之泛型

泛型的作用和约定

提高性能

拆箱和装箱 从值类型转换为引用类型为装箱,把引用类型转换为值类型为拆箱

装箱和拆箱很容易使用,但是性能损失比较大,尤其是遍历许多项的时候。

List<T>不使用对象,在使用时定义类型

var list = new List<int>();
list.Add(44);   // no boxing

int item = list[0];    // mo unboxing

不妨将List<T>看做一种新的类型,不在特意的和C++的模板相比较;

泛型类型的命名约定

  1. 泛型类型的名称用T作为前缀;

  2. 泛型类型允许使用任意类替代,且只使用了一个泛型类型就可以用T作为泛型类型的名称

     public class List<T>{}
     public class LinkedList<T>{}
    
  3. 若泛型类型有特定需求(例如必须实现一个接口或派生自基类),或者使用了两个或多个泛型类型

    public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);
    
    public delegate TOutput Converter<TInput, TOutput>(TInput from);
    
    public class SOrtedList<TKey, TValue>{}
    

泛型类的功能

默认值

创建泛型时,不能把null赋予泛型类型 ;在这个时候,我们就需要default,将null赋予引用类型,0赋值于值类型;

    public T GetDocument()
    {
        T doc = default(T);
        lock(this)
        {
            doc = documentQueue.Dequeue();
         }
         
         return doc;
     }

约束

若泛型类需要调用泛型类型中的方法,就必须添加约束where

泛型支持以下几种约束类型:

约束 说明
where T: struct 对于结构约束,T必须是值类型
where T: class T必须是引用类型
where T: IFoo T必须实现接口IFoo
where T: Foo T 必须派生基类Foo
where T: new() 构造函数约束,T必须有一个默认构造函数

泛型类型也可以合并多个约束,where T: IFoo, new()约束和MyMerge<T>申明指定,T必须实现IFoo接口,且必须有一个默认构造函数,示例如下所示:

    public class MyMerge<T> where T: IFoo, new()
    {
        // dosomething
    }

继承

泛型类型可以实现泛型接口,也可以派生自类,当然也可以派生自泛型基类;

public class Base<T>{}

public class Derived<T>: Base<T> {}    // 派生自泛型基类

当然,泛型类型派生自指定基类的类型:

public class Base<T>{}

public class Derived<T>: Base<string>{}

静态成员

泛型类的静态成员只能在类的一个实例中共享

// 定一个泛型类的静态成员
public class StaticDemo<T>
{
    public static int x;
}

StaticDemo<int>.x = 3;         // 第一组静态字段 = 3
StaticDemo<string>.x = 4;     // 第二组静态字段 = 4

Console.WriteLine(StaticDemo<int>.x);    // 这里将会输出3

泛型接口

使用泛型可以定义接口,在接口定义的方法可以带泛型参数

协变

在.Net中,参数类型是协变

例如,有Shape和Circle类,Circle派生自Shape,Display方法是为了接受Shape类型的参数

public void Display(Shape object){}

现在可以传递派生自Shape基类的任意对象,例如Circle,Rectangle

Circle c = new Circle(5);
Display(c);    // 这里便是协变

抗变

方法的返回类型是抗变

例如,若方法返回一个Shape,就不能把它赋予Circle,但是反过来就可以;

泛型接口的协变

若泛型类型使用out标注,泛型接口就是协变的,意味着返回类型也是T
若泛型类型使用in标注,泛型接口就是抗变的,表明传入的参数类型只能是T

posted @ 2020-02-21 00:11  醉曦  阅读(295)  评论(0编辑  收藏  举报