1. 程式人生 > >C#泛型約束

C#泛型約束

bstr 部分 name 一個 參數 list 多個 哈哈 override

本文將對各類泛型約束做一個簡單的總結。

文章一開始,給出演示代碼底稿(在此基礎上修改,演示,說明。)

class MyList<T> 
{
    List<T> list = new List<T>();
    public T this[int i]
    {
        get { return list[i]; }
        set { this.list[i] = value; }
    }
}

class Person
{
    public string Name { get; set; }
}

接下來,依次修改演示代碼底稿,來說明不同類型的泛型約束。

1 指定泛型參數為值類型

class MyList<T> where T:struct
{
...代碼省略部分
}

看看加上約束後的效果怎麽樣,按下面方式 實例化MyList 類 :

MyList<Person> list = new MyList<Person>();

你會發現,將產生如下錯誤提示:

類型“GencConstraint.Person”必須是不可為 null 的值類型才能用作泛型類型或方法“GencConstraint.MyList<T>”中的參數“T”。

使用下面的方式實例化MyList 類 ,將一切正常:

MyList<int> list = new MyList<int>();

2 指定泛型參數為引用類型

class MyList<T> where T:class 
{
...代碼省略部分 
}

修改泛型約束為 引用類型後,前面的錯誤提示消失,因為 Person 類是引用類型,滿足泛型約束。

3 指定泛型參數有無參的公共的構造函數

class MyList<T> where T:new()
{
...代碼省略部分
}

為Person類增加私有的無參構造函數,代碼如下:

class Person
{
    public string Name { get; set; }
    private Person()
    { 
        //do nothing
    }
}

實例化 MyList < Person > 類:

MyList<Person> list = new MyList<Person>();

出現編譯錯誤,提示:

“GencConstraint.Person”必須是具有公共的無參數構造函數的非抽象類型,才能用作泛型類型或方法“GencConstraint.MyList<T>”中的參數“T”。

哈哈,約束起作用了。

4 指定泛型參數 必須派生於指定基類

增加抽象類 SeniorAnimal

abstract class SeniorAnimal//高級動物
{
    public abstract void Speak();//會說話
    public abstract void UseTool();//會使用工具
}

指定泛型參數 必須派生於基類 SeniorAnimal

class MyList<T> where T : SeniorAnimal
{
     ...代碼省略部分
}

實例化 MyList < Person > 類(此時Person類還未繼承自 SeniorAnimal 類 ):

MyList<Person> list = new MyList<Person>();

出現編譯錯誤,提示:

不能將類型“GencConstraint.Person”用作泛型類型或方法“GencConstraint.MyList<T>”中的類型參數“T”。沒有從“‘GencConstraint.Person”到“GencConstraint.SeniorAnimal”的隱式引用轉換。

修改代碼,使Person類繼承自 SeniorAnimal 類

class Person : SeniorAnimal
{
    public string Name { get; set; }

    public override void Speak()
    {
        Console.WriteLine("我會說臟話!");
    }

    public override void UseTool()
    {
        Console.WriteLine("我會用砍刀!");
    }
}

再次編譯,一切正常。

5 指定泛型參數 必須實現指定接口

演示情況和第4點類似,就不提供演示代碼了。

6 指定泛型參數 必須派生於泛型類型U(裸類型約束)

class MyList<U> where U : SeniorAnimal
{
    List<U> list = new List<U>();
    public void ShowInfo<T>() where T : U
    {
    }
}

另外,可以為同一泛型參數應用多個約束。

好了,Game Over!

C#泛型約束