共用方式為


支援 LINQ 的 C# 功能

查詢運算式

查詢表達式會使用類似 SQL 或 XQuery 的宣告式語法來查詢 System.Collections.Generic.IEnumerable<T> 集合。 在編譯時,編譯器會將查詢語法轉換為方法呼叫,以實現 LINQ 提供者對標準查詢方法的實作。 應用程式會使用 using 指令來指定適當的命名空間,以控制範圍內的標準查詢運算符。 下列查詢表達式會使用字串陣列,根據字串中的第一個字元進行分組,並排序分組。

var query = from str in stringArray
            group str by str[0] into stringGroup
            orderby stringGroup.Key
            select stringGroup;

隱式型別變數(var)

您可以使用 var 修飾詞來指示編譯程式推斷並指派類型,如下所示:

var number = 5;
var name = "Virginia";
var query = from str in stringArray
            where str[0] == 'm'
            select str;

宣告為 var 的變數是強類型,就像您明確指定類型的變數一樣。 使用 var 使得建立匿名型態成為可能,但僅限於局部變數。 如需詳細資訊,請參閱隱含型別區域變數

物件與集合初始化器

物件和集合初始化表達式可讓您初始化物件,而不需明確呼叫 物件的建構函式。 通常在查詢表達式中使用初始化器,當它們將來源資料投影至新的資料型態時。 假設一個名為 Customer public NamePhone properties 的類別,你可以像以下程式碼中使用物件初始化器:

var cust = new Customer { Name = "Mike", Phone = "555-1212" };

繼續你的 Customer 類,假設有一個名為 IncomingOrders 的資料來源,對於每筆具有大的 OrderSize 的訂單,你想根據該訂單建立一個新的 Customer。 你可以對這個資料來源執行 LINQ 查詢,並利用物件初始化來填充一個集合:

var newLargeOrderCustomers = from o in IncomingOrders
                            where o.OrderSize > 5
                            select new Customer { Name = o.Name, Phone = o.Phone };

資料來源可能定義的屬性比類別多 Customer ,例如 OrderSize,但透過物件初始化,查詢回傳的資料會被塑造成想要的資料型態;你可以選擇與類別相關的資料。 因此,您現在擁有一個填入了您想要的新System.Collections.Generic.IEnumerable<T>Customer。 你也可以用 LINQ 的方法語法寫出前面的範例:

var newLargeOrderCustomers = IncomingOrders.Where(x => x.OrderSize > 5).Select(y => new Customer { Name = y.Name, Phone = y.Phone });

從 C# 12 開始,您可以使用 集合運算式 來初始化集合。

如需詳細資訊,請參閱:

匿名型別

編譯程式會建構 匿名型別。 只有編譯器能存取型別名稱。 匿名類型可讓您在查詢結果中暫時將一組屬性分組,而不需要定義個別的具名類型。 你可以用新的表達式和物件初始化器來初始化匿名型別,如圖所示:

select new {name = cust.Name, phone = cust.Phone};

從 C# 7 開始,您可以使用 Tuple 來建立未命名的類型。

擴充成員

擴充成員是靜態類別中與一種稱為接收者型別相關聯的靜態成員。 你可以把分機成員當作接收者類型來呼叫。 這個功能讓你可以在不實際修改現有類型的情況下「新增」成員。 標準查詢運算符是一組擴充方法,可為實作 IEnumerable<T>的任何類型提供LINQ查詢功能。

Lambda 運算式

Lambda 表達式是一種內聯函式,利用=>運算子將輸入參數與函數主體分離,並可在編譯時轉換為代理或表達式樹。 在 LINQ 程式設計中,當您對標準查詢運算符進行直接方法呼叫時,會遇到 Lambda 表達式。

表達式視為數據

查詢對像是可組合的,這表示您可以從 方法傳回查詢。 代表查詢的物件不會儲存產生的集合,而是在需要時產生結果的步驟。 從方法回傳查詢物件的優點是你可以進一步組合或修改它們。 因此,任何回傳查詢的方法的回傳值或 out 參數也必須包含該型別。 如果方法將查詢具體化為具體 List<T>Array 類型,則會傳回查詢結果,而不是查詢本身。 你仍然可以組合或修改從某個方法回傳的查詢變數。

在下列範例中,第一個方法 QueryMethod1 會傳回查詢做為傳回值,而第二個方法 QueryMethod2 會以參數傳回查詢 outreturnQ 在範例中)。 在這兩種情況下,回傳的都是查詢,而不是查詢結果。

IEnumerable<string> QueryMethod1(int[] ints) =>
    from i in ints
    where i > 4
    select i.ToString();

void QueryMethod2(int[] ints, out IEnumerable<string> returnQ) =>
    returnQ = from i in ints
              where i < 4
              select i.ToString();

int[] nums = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ];

var myQuery1 = QueryMethod1(nums);

以下 foreach 迴圈執行查詢 myQuery1

foreach (var s in myQuery1)
{
    Console.WriteLine(s);
}

將滑鼠指標放在上方 myQuery1 以查看其類型。

你也可以直接執行從 返回的 QueryMethod1 查詢,而不必使用 myQuery1

foreach (var s in QueryMethod1(nums))
{
    Console.WriteLine(s);
}

將滑鼠指標停留在呼叫 QueryMethod1 上方,以檢視其回傳類型。

QueryMethod2 傳回查詢結果作為 out 的參數值:

QueryMethod2(nums, out IEnumerable<string> myQuery2);

// Execute the returned query.
foreach (var s in myQuery2)
{
    Console.WriteLine(s);
}

您可以使用查詢組合來修改查詢。 在此情況下,會使用先前的查詢物件來建立新的查詢物件。 這個新物件會傳回與原始查詢物件不同的結果。

myQuery1 = from item in myQuery1
           orderby item descending
           select item;

// Execute the modified query.
Console.WriteLine("\nResults of executing modified myQuery1:");
foreach (var s in myQuery1)
{
    Console.WriteLine(s);
}