C#泛型

來源:互聯網
上載者:User

標籤:class   blog   code   http   com   get   

委託讓方法參數化,而泛型實現了型別參數化。

一、泛型型別的聲明規則:

  1、在類名稱後跟一對角括弧,括弧中為若干個型別參數,多個型別參數之間使用逗號進行分隔,型別參數實際上是個類型預留位置。如、public class MyClass<T>{},T只是個習慣,實際上用其他字母也完全可以。

  2、在類聲明的主體中使用型別參數來表示應該被替代的類型,一般是方法的參數類型,傳回型別,或者作為欄位、屬性的類型。

  樣本1:

    public class MyClass<T1, T2>    {        public T1 field1;   //在類內部泛型型別還能用        public T2 field2;        public T1 GetField1()  //作為傳回值        {             return field1;        }        public T2 GetField2()        {            return field2;        }        public void SetField1(T1 data)  //作為方法參數類型        {            field1 = data;        }        public void SetField2(T2 data)        {            field2 = data;        }    }

  泛型能夠根據傳入的不同類型,實施不同的處理。重用了代碼邏輯,將類型抽象了出來。

  泛型的類型約束,通過約束能夠對類型實參添加一定的限制條件,約束是通過使用內容關鍵字的where應用的,只需要在泛型型別聲明的角括弧後面使用where關鍵字,後面緊跟型別參數和約束類型,中間使用冒號分隔即可。

  類型約束一共有6種,如下所示:

約束類型 說明
where T : class 類型實參必須是參考型別,包括任何類、介面、委託或數群組類型
where T : struct 類型實參必須是實值型別,可以是任何實值型別,但不包括Nullable
where T : <基類名> 類型必須是指定的類或者它的衍生類別
where T : <介面名> 類型必須是實現了指定的介面或者實現了該介面的類型,可以指定多個介面約束,約束介面也可以是泛型的
where T : new() 類型實參必須有一個無參數的公用建構函式
where T : U 類型實參T必須是類型實參U,或者是U的衍生類別,這稱作裸類型約束

 

  同時還必須要注意,當需要添加多個類型約束時,約束之間用逗號分隔。同時對於某一個型別參數的多種約束類型,where字句與where字句之間沒有次序要求,但是對於where字句內部是有次序要求的。具體次序如下:

  1.   如果有class,struct,基類這三種類型約束,則必須放在第一位。
  2.   之後是介面約束,數量不限
  3.   如果有new(),則必須放在最後。

  如:

    public class TestType<T,V> where T : Person where V : new(){} //where與where字句沒有次序要求    public class TestType<T> where T : class,IList,new(){}      //where字句內部有類型要求

 

    class Program    {        static void Main(string[] args)        {            Person P = new Person();            P.Id = 1;            P.Name = "張三";            TestType<Person> tt = new TestType<Person>();            string str = tt.getType(P);            Console.WriteLine(str);     //輸出張三            Console.ReadKey();        }    }    public class TestType<T> where T : Person  //指定實參類型必須是Person類或Person類的衍生類別    {        public string getType(T data)        {            return data.Name;        }    }    public class Person    {        public int Id;        public string Name;    }

 泛型方法與泛型類很相似。一下給出兩個泛型方法的例子。

    class Program    {        static void Main(string[] args)        {            Person p = new Person();            p.Id = 1;            SetName<Person>(p);            Console.WriteLine(p.Name);  //輸出張飛            Console.ReadKey();        }        public static Person SetName<T>(T per) where T : Person        {            per.Name = "張飛";            return per;        }    }    class Person    {        public int Id { get; set; }        public string Name { get; set;  }    }    class Program    {        static void Main(string[] args)        {            string str = "你好!";            Console.WriteLine(GetMessage<string>(str));     //輸出System.String            Console.ReadKey();        }        public static Type GetMessage<T>(T Message)        {            return Message.GetType();        }    }    

 泛型的擴充方法,與擴充方法一樣,只是有點怪異罷了。給個樣本:

    class Program    {        static void Main(string[] args)        {            Person<string> per = new Person<string>();            per.Person<string>("關羽");   //這樣子來調用擴充方法,自己都看不懂牛得一B            Console.WriteLine(per.Name);            Console.ReadKey();        }    }    public static class Set    {        public static void Person<T>(this Person<T> p, T Name)        {            p.Name = Name;        }            }    public class Person<T>    {        public int Id { get; set; }        public T Name { get; set; }    }

泛型委派和非泛型委派也很相似,只是泛型委派進行了一層抽象,將中間涉及的操作類型以及傳回值類型抽象為了型別參數,以便更大限度地複用該委託。 

    public delegate T PrintDelegate<T>(T data);    class Program    {        static void Main(string[] args)        {            PrintDelegate<string> StrDelegate = PString; //委託的定義中,3個大T都是string            string outStr = StrDelegate("我是一個兵");   //調用委託            Console.WriteLine(outStr);         //輸出委託傳回值    我是一個兵我是一個兵            PrintDelegate<int> IntDelegate = PInt;  //型別參數傳入int,則參數類型,傳回值類型,都是int            int outInt = PInt(3);   //由於參數類型設為了int,因此只能綁定參數跟傳回值為int的方法            Console.WriteLine(outInt);  //輸出    6            Console.ReadKey();        }        public static string PString(string str)        {            return str + str;        }        public static int PInt(int i)        {            return i + i;        }    }

泛型的協變與逆變

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.