哪裡
where
可以在 C#中實現兩個目的:在泛型引數中鍵入約束,並過濾 LINQ 查詢。
在通用類中,讓我們考慮一下
public class Cup<T>
{
// ...
}
T 稱為型別引數。類定義可以對可以為 T 提供的實際型別施加約束。
可以應用以下型別的約束:
- 值型別
- 參考型別
- 預設建構函式
- 繼承和實施
值型別
在這種情況下,只能提供 struct
s(包括’原始’資料型別,如 int
,boolean
等)
public class Cup<T> where T : struct
{
// ...
}
參考型別
在這種情況下,只能提供類型別
public class Cup<T> where T : class
{
// ...
}
混合值/參考型別
有時,需要將型別引數限制為資料庫中可用的引數,這些引數通常會對映到值型別和字串。由於必須滿足所有型別限制,因此無法指定 where T : struct or string
(這不是有效的語法)。解決方法是將型別引數限制為 IConvertible
,其內建型別為“… Boolean,SByte,Byte,Int16,UInt16,Int32,UInt32,Int64,UInt64,Single,Double,Decimal,DateTime,Char 和 String。 “ 其他物件可能會實現 IConvertible,儘管這在實踐中很少見。
public class Cup<T> where T : IConvertible
{
// ...
}
預設建構函式
僅允許包含預設建構函式的型別。這包括值型別和包含預設(無引數)建構函式的類
public class Cup<T> where T : new
{
// ...
}
繼承和實施
只能提供從某個基類繼承或實現某個介面的型別。
public class Cup<T> where T : Beverage
{
// ...
}
public class Cup<T> where T : IBeer
{
// ...
}
約束甚至可以引用另一個型別引數:
public class Cup<T, U> where U : T
{
// ...
}
可以為型別引數指定多個約束:
public class Cup<T> where T : class, new()
{
// ...
}
前面的示例顯示了類定義的泛型約束,但是在提供型別引數的任何地方都可以使用約束:類,結構,介面,方法等
where
也可以是 LINQ 子句。在這種情況下,它類似於 SQL 中的 WHERE
:
int[] nums = { 5, 2, 1, 3, 9, 8, 6, 7, 2, 0 };
var query =
from num in nums
where num < 5
select num;
foreach (var n in query)
{
Console.Write(n + " ");
}
// prints 2 1 3 2 0