1.泛型:先聲明,延遲編譯。 public static void DoSome<T>(T t) { Console.WriteLine(t); } 這個方法就是泛型方法,先申明參數為T,不知道具體是什麼類型。 使用的時候DoSome<int>(1); DoSome<string>("hello") ...
1.泛型:先聲明,延遲編譯。 public static void DoSome<T>(T t) { Console.WriteLine(t); } 這個方法就是泛型方法,先申明參數為T,不知道具體是什麼類型。 使用的時候DoSome<int>(1); DoSome<string>("hello"); DoSome<Student>(new Student()); 當使用的時候,才會具體確定傳入參數是什麼 優點:為了讓一個方法,不同參數都可以使用。 2.有哪些? 泛型類 public class Person<T> { public T MyT{get;set;} } 泛型方法 public static void DoSomeThing<T>(T t) { Console.WriteLine(t); } 泛型介面 public interface IBrid<T> { void Show(T t); } 泛型委托 public delegate void DomeSome<T>(T t); 3.泛型約束 where 關鍵字 1.可以規定泛型的基類 public void SayHi<T>(T t) where T:Person { } T的類型要麼是基類Person,要麼是Person的子類或者子孫類 2.可以規定泛型實現的介面 public void SayHi<T>(T t) where T:IBrid {} 3.同時規定泛型實現介面和基類, 約束多個,用逗號 ,隔開 public void SayHi<T>(T t) where T : Person,IBrid {} 4.類型約束,值類型還是引用類型 where T : new() where T : struct 4.協變 out 逆變 in 有Animal類 有Dog類, Dog繼承Animal類 Animal animal = new Animal(); Animal a1 = new Dog(); 這樣沒錯;因為有繼承關係 但是: List<Animal> ans = new List<Animal>();正確 LIst<Animal> animals = new List<Dog>(); 這樣就會報錯,因為是2個不同的集合,沒有繼承關係 如果要是實現這個,就需要 用到協變 out 用系統自帶的IEnumerable介面 IEnumerable<Animal> ans1 = new List<Dog>();這樣就可以實現了。 或者自定義一個 介面 public interface ICustomerList<out T> { GetT(); //協變只能是返回T } 實現介面 public class CustomerList<T> : ICustomerList<T> { void GetT() { return default(T); } } CustomerList<Animal> animals = new CustomerList<Dog>();這樣就不會報錯了。 反過來就是協變 List<Dog> dogs = new List<Animal>(); 這樣也會報錯 就需要自定義一個介面 public interface ICustList<in T > { void Show(T t);//逆變只能傳入參數使用 } public class CustList<T> : ICustList<T> { public void Show(T t) { Console.WriteLine(t); } } CustList<Dog> dogs = new CustList<Animal>() 靜態構造函數和靜態屬性,都是常駐記憶體的,第一次使用,都會一直在。 每個泛型類,都會T的不同生成新的實例。 將靜態構造函數和靜態屬性還有泛型結合起來,就是泛型緩存。比dictionary字典靜態緩存更好用的一種。