1. 程式人生 > 實用技巧 >第16天c#基礎泛型和資料結構

第16天c#基礎泛型和資料結構

泛型

泛型類

允許您延遲編寫類或方法中的程式設計元素的資料型別的規範,直到實際在程式中使用它的時候。

泛型相當於型別佔位符

定義

 //定義格式:訪問修飾符 class 類名<T>    //T為替代的型別引數,可以用任意字母數字組合,
    //          {
    //                public T value;
    //          }
    //定義格式:訪問修飾符 class 類名<T>
    //          {
    //                public T value;
    //          }
    public
class Test<T> { public T value; public void Call() { Console.WriteLine(value.GetType()); } } public class Test1<T1,T2> //通常使用T,多個泛型時,使用逗號分隔<T0,T1,T2> { public T1 value1; public T2 value2; }

使用

泛型類在使用時,需要指定型別,類中使用代替符號

定義的變數都為該指定型別

        static void Main(string[] args)
        {
            Test<int> t1 = new Test<int>();
            Test<string> t = new Test<string>();
            t.value = "10";
            t.Call();

            Test1<string, int> t2 = new Test1<string, int>();

        }

泛型方法

T型別可以用在形參的型別,也可以用在返回值型別,也可以在方法內使用

定義

        //無參無返回值
        static void Fun1<T>()
        {
            Console.WriteLine("我是無參無返回值");
        }
        //無參有返回值
        static T Fun2<T>()
        {
            
            return default(T);
        }
        //有參無返回值
        static void Fun3<T>(T t1)
        {
            if(t1 is int )
            {
                Console.WriteLine("T1是int");

            }
        }
        //有參有返回值
        static T0 Fun4<T0, T1>(T0 t0, T1 t1)
        {
            return t0;
        }

使用

泛型方法在使用時,需要指定型別,方法中使用代替符號定義的變數或返回值,則都為該指定型別。

可以通過default類獲取該型別的預設值

        static void Main(string[] args)
        {
            Fun1<string>();
            int f = Fun2<int>();
            Console.WriteLine("無參有返回值:{0}",f);
            //Fun3<int>(1);                           //如果有引數 <>內可以省略
            Fun3(1);
            //string f4 = Fun4<string, int>("", 2);   //如果有引數 <>內可以省略
            string f4 = Fun4("abc", 2);
            Console.WriteLine("Fun4結果:{0}",f4);
        }

效果:

泛型約束

        //where T:struct                    指定型別,必須是值型別
        //where T:class                     指定型別,必須是引用型別
        //where T:new()                     指定型別,必須有無參數的公共建構函式
        //where T:類名                       指定型別,必須是該類名或該類的派生類
        //where T:介面名                     指定型別,必須是該介面或繼承該介面的型別
        //where T:U                         指定型別,該型別必須是U型別或U型別的派生型別
        //where T:class, new()              對同一個泛型進行多個約束,中間用“,”隔開
        //where T0:struct where T1:class    對多個泛型進行分別約束,兩個where間用空格隔開
    class Program
    {
        static void Main(string[] args)
        {
            Test<int> t1 = new Test<int>();
            //Test<string> t2 = new Test<string>();
            Test1<string> t2 = new Test1<string>();

            //Test2<Test3> t3 = new Test2<Test3>();
            Test4<Test3> t4 = new Test4<Test3>();
            Test4<Tool> t5 = new Test4<Tool>();

            Test5<IFly> t6 = new Test5<IFly>();
            Test5<Tool> t7 = new Test5<Tool>();

            Test6<Test3> t8 = new Test6<Test3>();
            t8.Function<Tool>();
        }
    }
    public class Test<T> where T:struct
    {

    }
    public class Test1<T> where T : class//引用型別
    {

    }
    public class Test2<T> where T : new()//必須有無引數的公共建構函式
    {

    }
    public class Test3
    {
        //private Test3()
        //{

        //}
    }
    public class Tool:Test3,IFly
    {
        public void Fly()
        {

        }
    }
    public class Test4<T> where T:Test3
    {

    }

    public interface IFly
    {
        void Fly();
    }
    public class Test5<T> where T :IFly
    {

    }

    public class Test6<U>
    {
        public void Function<T>() where T:U
        {

        }
    }

    public class Test7<T> where T:class,new()
    {

    }
    //public class Test8<T> where T:struct,new()
    //{

    //}
    /// <summary>
    /// 對每一個泛型進行單獨約束
    /// </summary>
    /// <typeparam name="T0"></typeparam>
    /// <typeparam name="T1"></typeparam>
    public class Test8<T0,T1> where T0:struct where T1:class
    {

    }

泛型介面

泛型例項:單例