Generic 泛型

 

一、一個基本的泛型結構如下

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Show<int>(123);

            People<string> People = new People<string>();
            People.Show("Tom");

            Console.ReadKey();
        }

        static void Show<T>(T a)
        {
            Console.WriteLine(a);
        }
    }

    class People<T>
    {
        public void Show(T b)
        {
            Console.WriteLine(b);
        }
    }

    public interface IFoo<in T>
    {
        void SetData(T obj);
    }

    public interface IFoo2<out T>
    {
        T GetData();
    }
}

泛型可以用在方法或類別或介面上。

 

在下面範例中 Show<int>(123); 可以簡化成 Show(123);

因為編譯器可以根據輸入參數反推出泛型型別。

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Show<int>(123);

            Show(123);

            Console.ReadKey();
        }

        static void Show<T>(T a)
        {
            Console.WriteLine(a);
        }
    }
}

這個例子也是一樣的 Show<People>(People.Create()); 可以簡化成 Show(People.Create());

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            People People = new People();

            Show<People>(People.Create());
            Show(People.Create());

            Console.ReadKey();
        }

        static T Show<T>(T a)
        {
            return a;
        }
    }

    class People
    {
        public People() { }
        public People Create()
        {
            return new People();
        }
    }
}

 

二、Constraints on type parameters

Constraint Description
where T : struct The type argument must be a value type. Any value type except Nullable<T> can be specified. For more information about nullable types, see Nullable types.
where T : class The type argument must be a reference type. This constraint applies also to any class, interface, delegate, or array type.
where T : unmanaged The type argument must not be a reference type and must not contain any reference type members at any level of nesting.
where T : new() The type argument must have a public parameterless constructor. When used together with other constraints, the new() constraint must be specified last.
where T : <base class name> The type argument must be or derive from the specified base class.
where T : <interface name> The type argument must be or implement the specified interface. Multiple interface constraints can be specified. The constraining interface can also be generic.
where T : U The type argument supplied for T must be or derive from the argument supplied for U.

註:在 C# 7.3 其 Constraints 還支援了 System.Enum、System.Delegate。

 

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            People<string> People = new People<string>();
            People.Show("Tom");

            //Error CS0452  The type 'int' must be a reference type'   
            //People<int> People = new People<int>();
            //People.Show(123);

            Console.ReadKey();
        }
    }

    class People<T> where T : class
    {
        public void Show(T b)
        {
            Console.WriteLine(b);
        }
    }
}

 

參考資料:

Generics (C# Programming Guide)

Constraints on type parameters (C# Programming Guide)

C#中陣列、ArrayList和List三者的區別