哪裡

where 可以在 C#中實現兩個目的:在泛型引數中鍵入約束,並過濾 LINQ 查詢。

在通用類中,讓我們考慮一下

public class Cup<T>
{
    // ...
}

T 稱為型別引數。類定義可以對可以為 T 提供的實際型別施加約束。

可以應用以下型別的約束:

  • 值型別
  • 參考型別
  • 預設建構函式
  • 繼承和實施

值型別

在這種情況下,只能提供 structs(包括’原始’資料型別,如 intboolean 等)

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