1、引入泛型
泛型不是一個簡單的語法糖,是框架升級支持的
List<string>就是泛型,為什么要有泛型?
List<T>是一個集合,可能是一組int,也可能是一組string,泛型就是用一個東西來滿足多種不同類型的需求的。
2、泛型方法
方法名稱后面加上尖括號,里面是類型參數,類型參數實際上就是一個類型T聲明,方法就可以用這個類型T了。泛型聲明方法時,並沒有寫死類型,T是什么,並不知道,T要等着調用的時候才指定。正式因為沒有寫死,才擁有了無限的可能。
泛型的設計思想--延遲聲明:推遲一切可以推遲的,一切能晚點再做的事,就晚一點再做。泛型不是一個簡單的語法糖,是框架升級支持的。泛型方法的性能跟普通方法一致,是最好的,而且還能一個方法滿足多個不同類型。
下面來看下代碼是怎么寫的:
public static void Show<T>(T tParameter)//, T t = default(T { Console.WriteLine("This is {0},parameter={1},type={2}", typeof(CommonMethod), tParameter.GetType().Name, tParameter); }
泛型類、泛型委托等和泛型方法聲明類似:
//泛型類 public class GenericClass<T> where T : ISports { } //泛型接口 public interface GenericInterface<S> { } //方形委托 public delegate void Do<T>() where T : ISports;
WebService WCF都不能用泛型,為什么?
因為這些是跨語言的,別的語言也能用,不支持泛型,服務在發布的時候是必須確定的,泛型在編譯時確定不了。
3、泛型約束
沒有約束,其實很受局限。
基類約束:
where T:BaseModel
1、可以把T當成基類---權利
2、T必須是BaseModel或者其子類
為什么要有約束?
因為有約束才有權利,自由主義的鼻祖洛克先生說過,有了法律,才有自由。
泛型:不同的類型都能進來,任何的類型都能過來,你知道我是誰?
where T:class 引用類型約束;引用類型
where T:struct
where T:new() 無參構造函數約束
public static void Show<T>(T tParameter) //where T : String//密封類約束的不行,因為沒有意義 //where T : People //where T : ISports where T : People, ISports, IWork, new() { Console.WriteLine("This is {0},parameter={1},type={2}", typeof(GenericConstraint), tParameter.GetType().Name, tParameter); Console.WriteLine($"{tParameter.Id} {tParameter.Name}"); tParameter.Hi(); //tParameter.Pingpang(); }
public T GetT<T, S>() //where T : class//引用類型約束 //where T : struct//值類型 where T : new()//無參數構造函數 where S : class { //return null; //return default(T);//default是個關鍵字,會根據T的類型去獲得一個默認值 return new T(); //throw new Exception(); }
4、協變、逆變
.net4.0才出現的,只能放在接口或者委托的泛型參數前面
out協變 covariant,修飾返回值,只能作為返回值
in 逆變 contravariant,修飾傳輸參數,只能作為傳入值
public class Bird { public int Id { get; set; } } public class Sparrow : Bird { public string Name { get; set; } } {//協變 IEnumerable<Bird> birdList1 = new List<Bird>(); IEnumerable<Bird> birdList2 = new List<Sparrow>(); Func<Bird> func = new Func<Sparrow>(() => null); ICustomerListOut<Bird> customerList1 = new CustomerListOut<Bird>(); ICustomerListOut<Bird> customerList2 = new CustomerListOut<Sparrow>(); } {//逆變 ICustomerListIn<Sparrow> customerList2 = new CustomerListIn<Sparrow>(); ICustomerListIn<Sparrow> customerList1 = new CustomerListIn<Bird>(); ICustomerListIn<Bird> birdList1 = new CustomerListIn<Bird>(); birdList1.Show(new Sparrow()); birdList1.Show(new Bird()); Action<Sparrow> act = new Action<Bird>((Bird i) => { }); } { IMyList<Sparrow, Bird> myList1 = new MyList<Sparrow, Bird>(); IMyList<Sparrow, Bird> myList2 = new MyList<Sparrow, Sparrow>();//協變 IMyList<Sparrow, Bird> myList3 = new MyList<Bird, Bird>();//逆變 IMyList<Sparrow, Bird> myList4 = new MyList<Bird, Sparrow>();//協變+逆變 }
5、泛型緩存
每個不同的T,都會生成一份不同的副本,適合不同的類型,需要緩存一份數據 場景,效率高
如有不對的地方,希望大家多指教!