• C#2008与.NET 3.5 高级程序设计读书笔记(10) 集合与泛型


    1.System.Collections命名空间的接口

    2.System.Collections命名空间的类类型

    3.System.Collections.Generic命名空间

    泛型接口也模拟了System.Collections命名空间下相应的非泛型类型:

    ICollection<T>

    IComparer<T>

    IDictionary<TKey,TValue>

    IEnumberable<T>

    IEnumberator<T>

    IList<T>

    4.泛型

    泛型介绍:泛型类和泛型方法同事具备可重用性、类型安全和效率,这是非泛型类和非泛型方法无法具备的。所谓泛型,即通过参数化类型实现同一份代码上操作多种数据类型,泛型编程是一种编程范式,它利用“参数化类型”将类抽象化,从而达到更灵活的复用。

    机制:C# 泛型类型替换是在运行时执行的,从而为实例化的对象保留了泛型类型信息。C#泛型代码在被编译为IL代码和无数据时,采用特殊的占位符来表示泛型类型,并用专有的IL指令支持泛型操作。而真正的泛型实例化工作以"on-demand"的方式,发生在JIT编译时。
    (1)、C#泛型由CLR在运行时支持,编译为IL时使用占位符和特列的IL指令,JIT时再真正的泛型实例化,区别于C++的编译时模板机制和Java的搽试法。
        a、可在各CLR语言之间无缝结合;
        b、不会像C++产生代码膨胀问题;
        c、也不会像Java的“假”泛型一样在性能上无所提升;
        d、对于值类型,每种值类型实例化一份,对于引用类型,只实例化为同一份代码。
    (2)、泛型类的要求
       

    class A <T1,T2>{}//合法
    class B:C <string,int>{} //合法
    class D<U,V>:C<U,V>{} //合法
    class E<U,V>:C<string,int>{} //合法
    class G:C<U,V>{} //非法
    /*
    总之就是父类的类型参数要么从子类得到确定,如第三个,要么已经确定,如第四个,第五个的父类不能确定类型参数
    */

    (3)、泛型类可以成为其它类的成员

    class C<T>
    {
    }

    class D<T>
    {
      
    public C<T> c;
      
      
    public void DoThings()
      
    {
        c.ToString();
    //没有用约束时,只能用object型的方法。
      }

    }

    (4)、泛型接口的要求同2点

    interface IList<T>{T[] GetElements();}
    interface IDictionary<T1,T2>
    {
      
    void Add(T1 key, T2 value);
    }

    class List<T>:IList<T>,IDictionary<string,T>
    {
      
    public T[] GetElements(){}
      
    public void Add(string key, T value){}
    }

    (5)、泛型委托

    delegate bool Predicate<T>(T value);
    class C
    {
      
    static bool F(int i ){}
      
    static bool G(string s){}
      
    static void Main()
      
    {
        Predicate
    <string> p1 = G;//C#2.0新语法
        Predicate<int> p2 = new Predicate<int>(F);//旧式语法写法
    }

    (6)、泛型方法--在方法声明上包含类型参数
      a、C#不支持泛型索引、属性、事件、构造、析构,但这些成员可以使用类的泛型参数;
      b、泛型方法可以用在泛和非泛类中

    public class Finder
    {
      
    public static Find<T>(T[] items, T item)
      
    {
        
    for(int i = 0 ; i < items.length ; i++)
        
    {
          
    if(items[i].Equal(item))return i;
        }

        
    return -1;
      }

    }



    int i = Finder.Find<int>(new int[]{1,2,3,4,5},2);

      c、泛型方法重载要求

    void F1<T>(T[] a,int i);
    void F1<U>(U[] a,int i); // Can't

    void F2<T>(int i );
    void F2(int i ); //yes

    void F3 <T>(T t) where T:A
    void F3 <T>(T t) where T:B //Can't

      d、泛型方法的重写

    abstract class Base{
      
    public abstract T Function<T,T1>(T t, T1 t1)where T1:T;
      
    public abstract T Function2<T> (T t) where T:IComparable;
    }


    class Derived:Base{
      
    public override string Function<string,int>(string s, int i){}
      
    public override string Function2<string> (string s) where string:IComparable{}//非法,重载无需声明约束
    }

    (7)、泛型约束--C#泛型的类型安全特点--要求显式的约束
      a、基类约束

    class Base{public void F1(){}}
    class Derived<T> where T:Base{
     
    public void F2(T t)
     
    {
      t.F1();
    //通过约束,能直接调用Base的方法
     }

    }

    泛型类型参数的约束:在定义泛型类时,可以对客户端代码能够在实例化类时用于类型参数的类型种类施加限制。如果客户端代码尝试使用某个约束所不允许的类型来实例化类,则会产生编译时错误。这些限制称为约束。约束是使用 where 上下文关键字指定的。下表列出了六种类型的约束:

  • 相关阅读:
    八月份总结+项目总结
    缓存图片技术
    7月份总结
    【转】JavaScript 事件顺序:冒泡和捕获
    【转】UTF16和UTF8什么区别?
    【转】javascript和html中unicode编码和字符转义的详解
    【笔记】javascript权威指南-第六章-对象
    Delphi 中的MD5实现方法《转》
    DELPHI 代码块集合
    Delphi Access 表中查询日期时间提示出错的问题《转》
  • 原文地址:https://www.cnblogs.com/engine1984/p/1776294.html
Copyright © 2020-2023  润新知