C#语法手册

泛型类声明与使用语法


泛型将类型参数的概念引入 .NET,这样就可设计具有以下特征的类和方法:在客户端代码声明并初始化这些类或方法之前,这些类或方法会延迟指定一个或多个类型。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSGDemoCSG006
{
    //https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/generics/

    //#csg006-01
    //声明一个泛型类型,
    public class GenericList<T>
    {
        //#csg006-01
        public void Add(T input)
        {
            //实现代码...
        }

        //#csg006-03
        //嵌套类的泛型声明
        private class Node
        {
            // T used in non-generic constructor.
            public Node(T t)
            {

            }

            //#csg006-03
            //使用类型T声明成员
            private T data;

            //#csg006-03
            //使用类型T声明属性
            public T Data
            {
                get { return data; }
                set { data = value; }
            }
        }
    }
    class TestGenericList
    {
        private class ExampleClass { }
        static void Main()
        {
            //#csg006-02
            //使用声明的泛型类型1
            GenericList<int> list1 = new GenericList<int>();
            list1.Add(1);

            //#csg006-02
            //使用声明的泛型类型2
            GenericList<string> list2 = new GenericList<string>();
            list2.Add("");

            //#csg006-02
            //使用声明的泛型类型3
            GenericList<ExampleClass> list3 = new GenericList<ExampleClass>();
            list3.Add(new ExampleClass());
        }
    }





    //#csg006-04
    //泛型类型的约束语法
    //T必须为值类型
    class GenericClass1<T> where T : struct
    {

    }

    //#csg006-04
    //T必须为引用类型
    class GenericClass2<T> where T : class
    {

    }

    //#csg006-04
    //类型参数必须是可为 null 或不可为 null 的引用类型。
    class GenericClass22<T> where T : class?
    {

    }

    //#csg006-04
    //类型参数必须是不可为 null 的类型。
    class GenericClass3<T> where T : notnull
    {

    }

    //#csg006-04
    //类型参数必须是不可为 null 的非托管类型。
    class GenericClass4<T> where T : unmanaged
    {

    }

    //#csg006-04
    //类型参数必须具有公共无参数构造函数。
    class GenericClass5<T> where T : new()
    {

    }

    //类型参数必须是指定的基类或派生自指定的基类。
    class GenericClass6<T> where T : SampleBaseClass
    {

    }

    //#csg006-04
    //类型参数必须是指定的基类或派生自指定的基类。
    //需要在C#8.0及更高版本中的可为 null 上下文中(#nullable enable)使用
    class GenericClass7<T> where T : SampleBaseClass?
    {

    }

    //#csg006-04
    //类型参数必须是指定的接口或实现指定的接口。
    //可指定多个接口约束。
    class GenericClass8<T> where T : SampleInterface
    {

    }

    //#csg006-04
    //类型参数必须是指定的接口或实现指定的接口。
    //可指定多个接口约束。
    //需要在C#8.0及更高版本中的可为 null 上下文中(#nullable enable)使用
    class GenericClass88<T> where T : SampleInterface?
    {

    }


    class GenericClass9<U>
    {
        //#csg006-04
        //为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。
        class GenericClass10<T> where T : U
        {

        }
    }


    public class SampleBaseClass { }

    public interface SampleInterface { }



    namespace CSG006_05
    {

        //#csg006-05
        //约束多个类型参数
        class BaseClass { }
        class TestClass<T, U>
            where U : struct
            where T : BaseClass, new()
        {

        }

    }

}