C# 泛型的類型約束


  對於沒有類型約束的泛型,其類型參數可以指定為任意類型。

  例如List<T>,其類型參數T是值類型(List<int>)或引用類型(List<object>)。

  有時候,我們希望泛型的類型參數只能是值類型或引用類型,這時就該論到類型約束上場了。

  約束要放到泛型方法或泛型類型聲明的末尾,並由關鍵字where來引入。

  在C#中,有4中類型約束可供使用。

1、引用類型約束

  這種約束用於確保使用的類型實參是應用類型。類型實參可以是任何類。接口。數組。委托,或者已知是引用類型的另外一個類型參數。例如以下聲明:

    class Sample<T> where T : class

Sample<object>、Sample<int[]>等引用類型作為類型實參的是有效的。

Sample<int>、Sample<Color>等值類型作為類型實參的無效的。

2、值類型約束

  這種約束用於確保使用的類型實參是值類型的,包括枚舉、結構體等,但可空類型除外。例如以下聲明:

    class Sample<T> where T : struct

Sample<int>、Sample<Color>等值類型作為類型實參的有效的。

Sample<object>、Sample<int[]>等引用類型作為類型實參的是無效的。

3、構造函數類型約束

  構造函數類型約束表示為T:new(),如果有多個類型約束,必須是所有類型參數的最后一個約束。它檢測類型實參是否有一個可用於類型實例的無參構造體。這適用於所有值類型;所有沒有顯式聲明構造體的非靜態類、非抽象類;所有顯式聲明了一個無參構造函數的非抽象類。實例如下:

    public T Create<T>() where T : new()
    {
        return new T();
    }

Create<int>()、Create<object>()都是有效的,但是Create<string>是無效的,因為string沒有無參構造函數。

4、轉換類型約束

  最后一種類型約束允許你指定另一種類型,類型實參必須可以通過一致性、引用或裝箱轉換隱式地轉換為該類型。一些例子如下:

        class Sample<T> where T : Stream { }//有效:Sample<Stream>(一致性轉換)
                                            //無效:Sample<string>
        class Sample<T> where T : IDisposable { }//有效:Sample<Stream>(引用轉換)
                                                //無效:Sample<string>
        class Sample<T> where T : IComparable<T> { }//有效:Sample<int>(裝箱轉換)
                                                //無效:Sample<FileInfo>
        class Sample<T,U> where T : U { }//有效:Sample<Stream,IDisposable>(引用轉換)
                                         //無效:Sample<string,IDisposable>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM