zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    XML文件操作指南
    数字判断和文本框提交事件,WEB SERVICE等
    【转】JS回车提交
    nchar,char,varchar与nvarchar区别
    .NET对象的序列化
    这是发布的第一篇随笔
    Eclipse!!!!!!!!!!!!!!!!!!
    关于JLink驱动升级后不能使用的解决方法
    Python基本问题笔记
    用Python写的学校图书馆视频下载工具
  • 原文地址:https://www.cnblogs.com/zuixime0515/p/12339866.html
Copyright © 2011-2022 走看看