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>

 

posted @ 2021-10-22 16:56  mshentai  阅读(1007)  评论(0编辑  收藏  举报