1. 概述html
public delegate void EventHandler<TEventArgs>(objcet sender, TEventArgs e);數據庫
public delegate TOutput Converter<TInput, TOutput>(TInput from);安全
public class SortedList<TKey, TValue> {}ide
2. 泛型類的功能函數
(1) 默認值:default關鍵字性能
public T GetDocument() { T doc = defalut(T); lock(this) { doc = documentQueue.Dequeue(); } return doc; }
(2) 約束:this
// TDocument 來代替 T // 對於編譯器而言,參數名不重要,但更具備可讀性 // 即TDocument類型必須實現IDocument接口 public class DocumentManager<TDocument> where TDocument : IDocument { //... }
(3) 繼承spa
public class Base<T> { } // 派生自泛型基類 public class Derived<T> : Base<T> { } // 派生自指定基類的類型 public class Derived<T> : Base<string> { }
public class Query<TRequest, TResult> { } public StringQuery<TRequest> : Query<TRequest, TResult> { }
(4) 靜態成員:泛型類的靜態成員只能在類的一個實例中共享。翻譯
// StaticDemo<T>類包含靜態字段X public classs StaticDemo<T> { public static int x; } // 同時對不一樣類型使用泛型類 StaticDemo<string>.x = 4; StaticDemo<int>.x =5; WriteLine(StaticDemo<string>.x); // writes 4
3. 泛型接口3d
(1) 協變與抗變:指對參數和返回值的類型進行轉換
private void button1_Click(object sender, EventArgs e) { string str = "這是一個string類型的實例, 函數Act的參數爲object, 這裏有協變的應用"; Act(str); } void Act(object obj) { return ; }
private void button2_Click(object sender, EventArgs e) { //注意這裏:Func的返回類型爲string, obj的類型爲object, string類型繼承自object object obj = Func(); } string Func() { return "這裏有抗變的應用"; }
(2) 泛型接口的協變:用out關鍵字標註,泛型接口就是協變的。即在接口實現代碼裏面,T只能用做返回類型,不能用做參數類型。
(3) 泛型接口的抗變:用in關鍵字標註,泛型接口就是抗變的。即在接口實現代碼裏面,T用做方法的輸入。
//泛型接口支持協變、逆變和不支持協變、逆變的對比 //1-定義一個接口IFoo,既不支持協變,也不支持逆變。 interface IFoo<T> { void Method1(T param); T Method2(); } //實現接口IFoo public class FooClass<T> : IFoo<T> { public void Method1(T param) { Console.WriteLine(default(T)); } public T Method2() { return default(T); } } //2-定義一個接口IBar支持對參數T的協變 interface IBar<out T> { T Method(); } //實現接口IBar public class BarClass<T> : IBar<T> { public T Method() { return default(T); } } //3-定義一個接口IBaz支持對參數T的逆變 interface IBaz<in T> { void Method(T param); } //實現接口IBaz public class BazClass<T> : IBaz<T> { public void Method(T param) { Console.WriteLine(param.ToString()); } } //---------------應用--------------- //1-定義兩個有繼承關係的類型,IParent和SubClass interface IParent { void DoSomething(); } public class SubClass : IParent { public void DoSomething() { Console.WriteLine("SubMethod"); } } //2-按照協變的邏輯,分別來使用IFoo和IBar //IFoo 不支持對參數T的協變 IFoo<SubClass> foo_sub = new FooClass<SubClass>(); IFoo<IParent> foo_parent = foo_sub;//編譯錯誤 //IBar 支持對參數T的協變 IBar<SubClass> bar_sub = new BarClass<SubClass>(); IBar<IParent> bar_parent = bar_sub; //3-按照逆變的邏輯,分別來使用IFoo和IBaz。 //IFoo 對參數T逆變不相容 IFoo<IParent> foo_parent = null; IFoo<SubClass> foo_sub = foo_parent;//編譯錯誤 //IBaz 對參數T逆變相容 IBaz<IParent> baz_parent = null; IBaz<SubClass> baz_sub = baz_parent;
部分說明轉自:https://www.cnblogs.com/icyJ/archive/2012/11/16/covariant.html
4. 泛型結構:很是類型於泛型類,知識沒有繼承特性。
Nullable<int> x; x = 4; x += 3; if (x.HasValue) { int y = x.Value; } x = null;
int? x1 = GetNullableType(); //GetNullableType()方法只是一個佔位符,返回一個可空的int int y1 = x1 ?? 0; //x1=null時賦值是默認值0
5. 泛型方法