標籤:style blog color 使用 問題 re
C#中有泛型類、泛型方法、泛型介面、泛型委派。下面先介紹前3種類型。
1.泛型類、泛型方法:
1 /// <summary> 2 /// 泛型類和泛型方法 3 /// </summary> 4 /// <typeparam name="T"></typeparam> 5 class MyClass<T> 6 { 7 public void Say(T msg) 8 { 9 Console.WriteLine(msg);10 }11 }
執行個體化這個類的時候,代碼如下:
1 MyClass<string> mc1 = new MyClass<string>();2 mc1.Say("yzk");3 4 MyClass<int> mc2 = new MyClass<int>();5 mc2.Say(20);
可以看到Say()方法中的參數類型早在執行個體化MyClass時就約束好了。
上面的代碼中是把泛型方法寫在泛型類中了,也可以把泛型方法寫在普通類中。
1 /// <summary> 2 /// 普通類中的泛型方法 3 /// </summary> 4 class MyClass1 5 { 6 public string Name { get; set; } 7 public int Age { get; set; } 8 public void Say<T>(T msg) 9 {10 Console.WriteLine(msg);11 }12 }
執行個體化這個類的時候,代碼如下:
1 MyClass1 mc1 = new MyClass1();2 mc1.Name = "yzk";3 mc1.Age = 18;4 mc1.Say<int>(10);5 mc1.Say<string>("hello");6 mc1.Say<string>(mc1.Name);
可以看到,在調Say方法的時候,<>中寫什麼類型,後面的參數就必須是什麼類型。
2.泛型介面
1 class Person:IComparable<Person> 2 { 3 public string Name { get; set; } 4 public int Age { get; set; } 5 6 public int CompareTo(Person other) 7 { 8 return other.Age - this.Age; 9 }10 }
上面的代碼,首先讓Person類實現了泛型的IComparable介面,可以看到裡面的CompareTo方法參數也是Person類型,就不用再轉換other了,這是實現泛型介面的好處。與之類似的還有IComparer<T>介面,看下面2個比較子:
1 class SortByName:IComparer<Person> 2 { 3 4 public int Compare(Person x, Person y) 5 { 6 return y.Name.Length - x.Name.Length; 7 } 8 } 9 10 class SortByAge:IComparer<Person>11 {12 13 public int Compare(Person x, Person y)14 {15 return x.Age - y.Age;16 }17 }
泛型中的類型推斷,代碼如下:
1 /// <summary> 2 /// 普通類中的泛型方法 3 /// </summary> 4 class MyClass1 5 { 6 public string Name { get; set; } 7 public int Age { get; set; } 8 public void Say<T>(T msg) 9 {10 Console.WriteLine(msg);11 }12 }
但是在使用的時候,是這個樣子的:
1 MyClass1 mc1 = new MyClass1();2 mc1.Name = "yzk";3 mc1.Age = 18;4 mc1.Say(10);5 mc1.Say("hello");6 mc1.Say(mc1.Name);
可以看到,雖然Say方法是泛型的,但是調用的時候,不寫參數類型,也能自動推斷,這就是泛型中的類型推斷。
關於泛型方法重載的問題:
1 class MyClass4 2 { 3 //如果在MyClass4寫了泛型(MyClass4<T>),那麼下面的Show方法可以寫成這個樣子:Show(T msg),不必要寫<T> 4 public void Show<T>(T msg) 5 { 6 Console.WriteLine(msg); 7 } 8 9 public void Show(string msg)10 {11 Console.WriteLine(msg);12 }13 }
在執行個體化上面的類的時候,我們這麼寫:
1 MyClass4 mc4 = new MyClass4();2 mc4.Show("abc");
那麼這個Show到底是調用了泛型方法,還是普通方法呢?且看編譯器是如何編譯的
new MyClass4().Show("abc");
編譯器(遵循簡單方便原則)看到有不帶泛型的方法就直接調用了。而如果這麼寫就是調用泛型方法:
mc4.Show<string>("abc");
編譯後的代碼如下:
new MyClass4().Show<string>("abc");
泛型約束:
在寫泛型的時候,可以約束泛型必須是某個類型或繼承至某個類型或者實現某個介面,文法如下:
1 class MyClass<T,K,V,w,Y,D>2 where T:struct //約束T必須是實值型別;3 where K:class //約束K必須是參考型別。4 where V:Icomparable //約束V必須是實現Icomparable介面的類型或其子類類型.5 where w:Person //約束w必須是Person類型或其子類類型.6 where Y:K //約束Y必須是K類型或其子類類型。7 where D:new() //約束參數必須有無參的公用建構函式。放在最後。