泛型(四)
泛型方法(C# 程式設計指南)
泛型方法是通過型別引數宣告的方法,如下所示:
static void Swap<T>(ref T lhs, ref T rhs)
{
T temp;
temp = lhs;
lhs = rhs;
rhs = temp;
}
如下示例演示使用型別引數的 int
呼叫方法的一種方式:
public static void TestSwap()
{
int a = 1;
int b = 2;
Swap<int>(ref a, ref b);
System.Console.WriteLine(a + " " + b);
}
還可省略型別引數,編譯器將推斷型別引數。 如下 Swap
呼叫等效於之前的呼叫:
Swap(ref a, ref b);
型別推理的相同規則適用於靜態方法和例項方法。 編譯器可基於傳入的方法引數推斷型別引數;而無法僅根據約束或返回值推斷型別引數。 因此,型別推理不適用於不具有引數的方法。 型別推理髮生在編譯時,之後編譯器嘗試解析過載的方法簽名。 編譯器將型別推理邏輯應用於共用同一名稱的所有泛型方法。 在過載解決方案步驟中,編譯器僅包含在其上型別推理成功的泛型方法。
在泛型類中,非泛型方法可訪問類級別型別引數,如下所示:
class SampleClass<T>
{
void Swap(ref T lhs, ref T rhs) { }
}
如果定義一個具有與包含類相同的型別引數的泛型方法,則編譯器會生成警告 CS0693
,因為在該方法範圍內,向內 T
提供的引數會隱藏向外 T
提供的引數。 如果需要使用型別引數(而不是類例項化時提供的引數)呼叫泛型類方法所具備的靈活性,請考慮為此方法的型別引數提供另一識別符號,如下方示例中 GenericList2<T>
所示。
class GenericList<T>
{
// CS0693
void SampleMethod<T>() { }
}
class GenericList2<T>
{
//No warning
void SampleMethod<U>() { }
}
使用約束在方法中的型別引數上實現更多專用操作。 此版 Swap<T>
現名為 SwapIfGreater<T>
,僅可用於實現 IComparable<T>
的型別引數。
void SwapIfGreater<T>(ref T lhs, ref T rhs) where T : System.IComparable<T>
{
T temp;
if (lhs.CompareTo(rhs) > 0)
{
temp = lhs;
lhs = rhs;
rhs = temp;
}
}
泛型方法可過載在數個泛型引數上。 例如,以下方法可全部位於同一類中:
void DoWork() { }
void DoWork<T>() { }
void DoWork<T, U>() { }
泛型和陣列(C# 程式設計指南)
在 C# 2.0 和更高版本中,下限為零的單維陣列自動實現 IList<T>
。 這可使你建立可使用相同程式碼迴圈訪問陣列和其他集合型別的泛型方法。 此技術的主要用處在於讀取集合中的資料。 IList<T>
介面無法用於新增元素或從陣列刪除元素。 如果在此上下文中嘗試對陣列呼叫 IList<T>
方法(例如 RemoveAt
),則會引發異常。
如下程式碼示例演示具有 IList<T>
輸入引數的單個泛型方法如何可迴圈訪問列表和陣列(此例中為整數陣列)。
class Program
{
static void Main()
{
int[] arr = { 0, 1, 2, 3, 4 };
List<int> list = new List<int>();
for (int x = 5; x < 10; x++)
{
list.Add(x);
}
ProcessItems<int>(arr);
ProcessItems<int>(list);
}
static void ProcessItems<T>(IList<T> coll)
{
//IsReadOnly為陣列返回True,為List返回False。
System.Console.WriteLine
("IsReadOnly returns {0} for this collection.",
coll.IsReadOnly);
//以下語句導致陣列的執行時異常,但不會導致List。
//coll.RemoveAt(4);
foreach (T item in coll)
{
System.Console.Write(item.ToString() + " ");
}
System.Console.WriteLine();
}
}
相關文章
- TypeScript學習(四)—— 介面和泛型TypeScript泛型
- 泛型類、泛型方法及泛型應用泛型
- 【java】【泛型】泛型geneticJava泛型
- Java基礎知識掃盲(四)——泛型Java泛型
- 泛型類和泛型方法泛型
- 泛型--泛型萬用字元和泛型的上下限泛型字元
- Go 泛型之泛型約束Go泛型
- TypeScript 泛型介面和泛型類TypeScript泛型
- 泛型泛型
- 泛型最佳實踐:Go泛型設計者教你如何用泛型泛型Go
- 型別 VS 泛型型別泛型
- TypeScript 泛型型別TypeScript泛型型別
- 泛型類、泛型方法、型別萬用字元的使用泛型型別字元
- 泛型viewmodle泛型View
- Java泛型Java泛型
- Go 泛型Go泛型
- 泛型(Generic)泛型
- 泛型(一)泛型
- 泛型(三)泛型
- 泛型(二)泛型
- 泛型(五)泛型
- 【譯】在非泛型類中建立泛型方法泛型
- 泛型型別(.NET 指南)泛型型別
- Java函式泛型List引數,操作泛型元素Java函式泛型
- Go 官方出品泛型教程:如何開始使用泛型Go泛型
- 【C#】-泛型C#泛型
- TypeScript 工具泛型TypeScript泛型
- C#泛型C#泛型
- C# 泛型C#泛型
- Java-泛型Java泛型
- spring泛型注入Spring泛型
- go泛型教程Go泛型
- python使用泛型Python泛型
- Java(7)泛型Java泛型
- 介面即泛型泛型
- TypeScript 泛型限定TypeScript泛型
- Java+泛型Java泛型
- 泛型總結泛型