所謂泛型,即通過參數化類型來實作在同一份代碼上操作多種資料類型。
泛型程式設計是一種程式設計範式,它利用“參數化類型”将類型抽象化,進而實作更為靈活的複用。在定義泛型類時,在對用戶端代碼能夠在執行個體化類時,可以用類型參數的類型種類施加限制。
在C# 2.0中,方法可以定義特定于其執行範圍的泛型參數,如下所示:
<a></a>
即使包含類不适用泛型參數,你也可以定義方法特定的泛型參數,如下所示:
注意:屬性和索引器不能指定自己的泛型參數,它們隻能使用所屬類中定義的泛型參數進行操作。
在調用泛型方法的時候,你可以提供要在調用場所使用的類型,如下所示:
//調用泛型方法
MyClass myClass = new MyClass();
myClass.MyMethod<int>(3);
泛型推理:
在調用泛型方法時,C#編譯器足夠聰明,基于傳入的參數類型來推斷出正确的類型,并且它允許完全省略類型規範,如下所示:
//泛型推理機制調用泛型方法
myClass.MyMethod(3);
注意:泛型方法無法隻根據傳回值的類型推斷出類型,代碼如下:
泛型方法中泛型參數的限制,如下:
無法為類級别的泛型參數提供方法級别的限制。類級别泛型參數的所有限制都必須在類作用範圍中定義,代碼如下所示
而下面的代碼是正确的:
泛型參數虛方法的重寫:子類方法必須重新定義該方法特定的泛型參數,代碼如下
同時子類中的泛型方法不能重複基類泛型方法的限制,這一點和泛型類中的虛方法重寫是有差別的,代碼如下
子類方法調用虛拟方法的基類實作:它必須指定要代替泛型基礎方法類型所使用的類型實參。你可以自己顯式的指定它,也可以依靠類型推理(如果可能的話)代碼如下:
在某個類中定義的委托可以使用該類的泛型參數,代碼如下
委托推理:C#2.0使你可以将方法引用的直接配置設定轉變為委托變量。将上面的代碼改造如下
泛型委托的限制:
委托級别的限制隻在聲明委托變量和執行個體化委托時使用,類似于在類型和方法的作用範圍中實施的其他任何限制。
泛型和反射
在Net2.0當中,擴充了反射以支援泛型參數。類型Type現在可以表示帶有特定類型的實參(或綁定類型)或未指定類型的泛型(或稱未綁定類型)。像C#1.1中那樣,您可以通過使用typeof運算符或通過調用每個類型支援的GetType()來獲得任何類型的Type。代碼如下:
typeof還可以對未綁定的泛型進行操作,代碼如下
請注意"<>"的用法。要對帶有多個類型參數的未綁定泛型類進行操作,請在"<>"中使用","
Type類中添加了新的方法和屬性,用于提供有關該類型的泛型方面的反射資訊,見MSDN。
如果用戶端代碼嘗試使用某個限制所不允許的類型來執行個體化類,則會産生編譯時錯誤。這些限制稱為限制。限制是使用 where 上下文關鍵字指定的。
下表列出了五種類型的限制:
限制
說明
T:struct
類型參數必須是值類型。可以指定除 Nullable 以外的任何值類型。
T:class
類型參數必須是引用類型,包括任何類、接口、委托或數組類型。
T:new()
類型參數必須具有無參數的公共構造函數。當與其他限制一起使用時,new() 限制必須最後指定。
T:<基類名>
類型參數必須是指定的基類或派生自指定的基類。
T:<接口名稱>
類型參數必須是指定的接口或實作指定的接口。可以指定多個接口限制。限制接口也可以是泛型的。
T:U
為 T 提供的類型參數必須是為 U 提供的參數或派生自為 U 提供的參數。這稱為裸類型限制.
1.常見的
public class MyClass5<T> where T :IComparable { }
2.限制放在類的實際派生之後
public class B { }
public class MyClass6<T> : B where T : IComparable { }
3.可以繼承一個基類和多個接口,且基類在接口前面
public class MyClass7<T> where T : B, IComparable, ICloneable { }
public class MyClass8<T> where T : new() { }
2.可以将構造函數限制和派生限制組合起來,前提是構造函數限制出現在限制清單的最後
public class MyClass8<T> where T : IComparable, new() { }
public class MyClass9<T> where T : struct { }
2.與接口限制同時使用,在最前面(不能與基類限制,構造函數限制一起使用)
public class MyClass11<T> where T : struct, IComparable { }
常見的
public class MyClass10<T> where T : class { }
public class MyClass12<T, U> where T : IComparable where U : class { }
public class B<T>{ }
1. 在從泛型基類派生時,可以提供類型實參,而不是基類泛型參數
public class SubClass11 : B<int>
{ }
2.如果子類是泛型,而非具體的類型實參,則可以使用子類泛型參數作為泛型基類的指定類型
public class SubClass12<R> : B<R>
3.在子類重複基類的限制(在使用子類泛型參數時,必須在子類級别重複在基類級别規定的任何限制)
public class B<T> where T : ISomeInterface { }
public class SubClass2<T> : B<T> where T : ISomeInterface { }
4.構造函數限制
public class B<T> where T : new()
{
public T SomeMethod()
{
return new T();
}
}
public class SubClass3<T> : B<T> where T : new(){ }
(C#2.0泛型機制支援在"方法聲名上包含類型參數",這就是泛型方法)
1.泛型方法既可以包含在泛型類型中,又可以包含在非泛型類型中
public class MyClass5
public void MyMethod<T>(T t){ }
2.泛型方法的聲明與調用
3.泛型方法的重載
4.泛型方法的覆寫
(1)public class MyBaseClass1
public virtual void MyMothed<T>(T t) where T : new() { }
public class MySubClass1:MyBaseClass1
public override void MyMothed<T>(T t) //不能重複任何限制
{ }
(2)public class MyBaseClass2
public virtual void MyMothed<T>(T t)
public class MySubClass2 : MyBaseClass2
public override void MyMothed<T>(T t) //重新定義泛型參數T
編譯器隻允許将泛型參數隐式強制轉換到 Object 或限制指定的類型。
變通方法:使用臨時的 Object 變量,将泛型參數強制轉換到其他任何類型
1
2
3
4
5
6
7
8
<code>class</code> <code>MyClass2<T></code>
<code>{</code>
<code> </code><code>void</code> <code>SomeMethod(T t)</code>
<code> </code><code>{</code>
<code> </code><code>object</code> <code>temp = t;</code>
<code> </code><code>BaseClass obj = (BaseClass)temp;</code>
<code> </code><code>}</code>
<code>}</code>
編譯器允許您将泛型參數顯式強制轉換到其它任何接口,但不能将其轉換到類
使用臨時的 Object 變量,将泛型參數強制轉換到其他任何類型
沒有整理與歸納的知識,一文不值!高度概括與梳理的知識,才是自己真正的知識與技能。 永遠不要讓自己的自由、好奇、充滿創造力的想法被現實的架構所束縛,讓創造力自由成長吧! 多花時間,關心他(她)人,正如别人所關心你的。理想的騰飛與實作,沒有别人的支援與幫助,是萬萬不能的。
本文轉自wenglabs部落格園部落格,原文連結:http://www.cnblogs.com/arxive/p/6179972.html,如需轉載請自行聯系原作者