<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    小議泛型

    Posted on 2008-09-22 19:25 H2O 閱讀(221) 評論(0)  編輯  收藏 所屬分類: java
    泛型
    一、什么是泛型?
    通過泛型可以定義類型安全類,而不會損害類型安全、性能或工作效率

    二、實例化泛型
    1、可以使用任何類型來聲明和實例化
    2、申明和實例話都必須用一個特定的類型來代替一般類型T
    3、例子:
    //原來寫法
    Public   class   Stack
    {
    object[]   m_Items;
    public   void   Push(object   item)
    {...}
    public   object   Pop()
    {...}
    }
    Stack   stack   =   new   Stack();
    stack.Push(1);
    int   number   =   (int)stack.Pop();

    //有了泛型后
    Public   class   Stack <T>
    {
    T[]   m_Items;
    public   void   Push(T   item)
    {...}
    public   T   Pop()
    {...}
    }
    Stack <int>   stack   =   new   Stack <int> ();
    stack.Push(1);
    int   number   =   (int)stack.Pop();

    三:泛型的好處
    1、一次性的開發、測試和部署代碼,通過任何類型來重用它
    2、編譯器支持和類型安全
    3、不會強行對值類型進行裝箱和取消裝箱,或者對引用類型進行向下強制類型轉換,所以性能得到顯著提高。
    注:值類型大概可以提高200%,引用類型大概為100%

    四:多個泛型
    1、單個類型可以定義多個泛型

    五:泛型別名
    1、在文件頭部使用using   為特定類型取別名,別名作用范圍是整個文件
    2、例子
    using   List   =   LinkedList <int,string> ;
    class   ListClient
    {
    static   void   Main(string[]   args)
    {
    List   list   =   new   List();
    list.AddHead(123, "AAA ");
    }
    }

    五:泛型約束
    (1)、派生約束
    如:
    public   class   LinkedList <K,T>   where   K:IComparable
    {
    T   Find(K   key)
    {
    if   (str.Key.CompareTo(key)   ==   0)//只有實現這個接口才可比較
    }
    }

    注意:
    1、所有的派生約束必須放在類的實際派生列表之后
    如:public   class   LinkedList <K,T> :IEnumerable <T>   where   K:IComparable <K>
            {...}
    2、一個泛型參數上可以約束多個接口(用逗號分隔)
    public   class   LinkedList <K,T>   where   K:IComparable <K> ,IConvertible
    3、在一個約束中最多只能使用一個基類
    4、約束的基類不能是密封類或靜態類
    5、不能將System.Delegate或System.Array約束為基類
    6、可以同時約束一個基類以及一個或多個接口,但是該基類必須首先出現在派生約束列表中。
    7、C#允許你將另一個泛型參數指定為約束
    public   class   MyClass <T,U>   where   T:U
    {...}
    8、可以自己定義基類或接口進行泛型約束
    9、自定義的接口或基類必須與泛型具有一致的可見性

    (2)、構造函數約束
    如:
    class   Node   <K,T>   where   T:new()
    {
    }
    注意:
    1、可以將構造函數的約束和派生約束結合起來,前提是構造函數的約束出現在約束列表中的最后

    (3)、引用/值類型約束
    1、可以使用struct約束將泛型參數約束為值類型(如int、bool、enum),或任何自定義結構
    2、同樣可以使用class約束將泛型參數約束為引用類型
    3、不能將引用/值類型約束與基類約束一起使用,因為基類約束涉及到類
    4、不能使用結構和默認構造函數約束,因為默認構造函數約束也涉及到類
    5、雖然您可以使用類和默認構造函數約束,但是這樣做沒有任何價值
    6、可以將引用/值類型約束與接口約束組合起來,前提是引用/值類型約束出現在約束列表的開頭

    六:泛型和強制類型轉換
    1、C#編譯器只允許將泛型參數隱式轉換到Object或約束指定的類型
    如:
    interface   IS{...}
    class   BaseClass{...}
    class   MyClass <T>   where   T:BaseClass,IS
    {
    void   SomeMethod(T   t)
    {
    IS   obj1   =   t;
    BaseClass   obj2   =   t;
    object   obj3   =   t;
    }
    }
    2、編譯器允許你將泛型參數顯示強制轉換到其他任何借口,但不能將其轉換到類
    interface   IS{...}
    class   SomeClass{...}
    class   MyClass   <T>   //沒有約束
    {
    void   SomeMethod(T   t)
    {
    IS   obj1   =   (IS)t;   //可以
    SomeClass   obj2   =   (SomeClass)t   //不可以
    }
    }
    3、可以使用臨時的Object變量,將泛型參數強制轉換到其他任何類型
    class   SomeClass{...}
    class   MyClass   <T>  
    {
    void   SomeMethod(T   t)
    {
    object   temp   =   t;
    SomeClass   obj   =   (SomeClass)temp;//可以
    }
    }
    注意:這里只是告訴你這樣寫是可以的,但是要不要這樣寫?不要這樣寫,因為如果t確實沒有繼承SomeClass編譯沒錯但是運行就會出錯
    4、解決上面強制轉換問題,可以使用is和as運算符進行判斷
    public   class   MyClass <T>
    {
    public   void   SomeMethod <T   t>
    {
    if   (t   is   int   ){...}
    if   (t   is   LinkedList <int,string> ){...}
    //如果泛型參數的類型是所查詢的類型,則is運算符返回true
    string   str   =   t   as   string;
    //如果這寫類型兼容,則as將執行強制類型轉換,否則將返回null
    if   (str   !=   null){...}
    LinkedList <int,string>   list   =   t   as   LinkedList <int,string> ;
    if   (list   !=   null){...}
    }
    }

    七:繼承和泛型
    1、在從泛型基類派生,可以提供類型實參,而不是基類泛型參數
    public   class   BaseClass <T> {...}
    public   class   SubClass:BaseClass <int>
    2、如果子類是泛型,而非具體的類型實參,則可以使用子類泛型參數作為泛型基類的指定類型
    public   class   BaseClass <TT> {...}
    public   class   SubClass <T> :BaseClass <T> {...}
    3、在使用子類泛型參數時,必須在子類級別重復在基類級別規定的任何約束
    4、基類可以定義其簽名使用泛型參數的虛禮方法,在重寫它們時,子類必須在方法簽名中提供相應的類型。
    如:
    public   class   BaseClass <T>
    {
    public   virtual   T   SomeMethod()
    {...}
    }
    public   class   SubClass:BaseClass <int>
    {
    public   override   int   SomeMethod()
    {...}
    }
    5、如果該子類是泛型,則它還可以在重寫時使用它自己的泛型參數
    public   class   SubClass <T> :BaseClass <T>
    {
    public   override   T   SomeMethod()
    {...}
    }
    6、你可以定義泛型接口、泛型抽象類,甚至泛型抽象方法。
    7、不能對泛型參數使用+或+=之類的運算符
    public   class   Calculator <T>
    {
    public   T   Add   (T   arg1,T   arg2)
    {
    return   arg1   +   arg2;//錯誤
    }
    }
    但是我們可以通過泛型抽象類、接口來實現在個功能,因為實現泛型抽象類、接口我們就已經明確傳一個參數了,就可以執行諸如+這樣的操作。

    八:泛型方法
    1、方法可以定義特定于其執行范圍的泛型參數
    public   class   MyClass <T>
    {
    public   void   MyMethod <X> (X   x)
    {...}
    }
    2、即使各包含類根本不使用泛型,你也可以定義方法特定的泛型參數
    public   class   MyClass
    {
    public   void   MyMethod <T> (T   t)
    {...}
    }
    注意:該功能只使用于方法,屬性,索引器只能使用在類的作用范圍中定義的泛型參數。
    3、調用泛型方法
    MyClass   obj   =   new   MyClass();
    obj.MyMethod <int> (3);
    也可以這樣:
    MyClass   obj   =   new   MyClass();
    obj.MyMethod(3);   //該功能稱為泛型推理
    4、泛型方法也可以有自己的泛型參數約束
    pubic   class   MyClass
    {
    public   void   SomeMethod <T> (T   t)   where   T:IComparable <T>
    {...}
    }
    5、子類方法實現不能重復在父級別出現的約束
    public   class   BaseClass
    {
    public   virtual   void   SomeMethod <T> (T   t)where   T:new()
    {...}
    }
    pubic   class   SubClass:BaseClass
    {
    public   override   void   SomeMethod <T> (T   t)//不能再有約束
    {...}
    }
    6、靜態方法
    靜態方法可以定義特定的泛型參數和約束
    public   class   MyClass <T>
    {
    public   static   T   SomeMethod <X> (T   t,X   x)
    {...}
    }
    int   number   =   MyClass <int> .SomeMethod <string> (3, "AAA ");
    或者:int   mumber   =   MyClass <int> .SomeMethod(3, "AAA ");

    九:泛型委托
    1、在某個類中定義的委托可以利用該類的泛型參數
    2、委托也可以定義自己的泛型參數

    posts - 0, comments - 21, trackbacks - 0, articles - 101

    Copyright © H2O

    主站蜘蛛池模板: 亚洲人成网站18禁止一区 | 久久久亚洲欧洲日产国码二区| 亚洲综合色成在线播放| 亚洲国产区男人本色| 国产精品久久久久久久久久免费 | 视频一区二区三区免费观看| 午夜一区二区免费视频| 国产亚洲精品成人AA片| 在线观看免费污视频| 亚洲日韩激情无码一区| 亚洲综合综合在线| 91香蕉国产线在线观看免费| 亚洲激情在线观看| 久久精品免费一区二区| 亚洲午夜精品一级在线播放放| jizz免费在线影视观看网站| 国产亚洲人成网站在线观看不卡| 亚洲熟女精品中文字幕| 国产精品免费一级在线观看| 人体大胆做受免费视频| 久久精品国产69国产精品亚洲| 亚洲6080yy久久无码产自国产| 中文字幕免费高清视频| 97久久国产亚洲精品超碰热| 国产麻豆免费观看91| 亚洲狠狠久久综合一区77777| 日韩人妻一区二区三区免费| 亚洲国产精品成人久久久| a视频在线观看免费| 亚洲综合激情视频| 欧洲美熟女乱又伦免费视频| 一级毛片免费视频网站| 国产资源免费观看| 国产99视频精品免费视频76| 亚洲精品视频在线| 日本最新免费不卡二区在线| 成人免费777777被爆出| 国产成人99久久亚洲综合精品| 久久国产乱子伦精品免费不卡| 自拍偷自拍亚洲精品被多人伦好爽 | 大陆一级毛片免费视频观看|