查詢作業中的型別關聯性 (LINQ)
更新:2007 年 11 月
若要有效撰寫查詢,您應該了解整個查詢作業中的變數型別如何互相關聯。若能了解這些關聯性 (Relationship),就更容易理解文件中的 LINQ 範例和程式碼範例。此外,您還可以知道使用 var 對變數進行隱含型別處理時,系統在幕後執行的作業。
在資料來源、查詢本身和查詢執行中,LINQ 查詢作業都為強型別 (Strongly Typed)。查詢中變數的型別,必須與資料來源中項目的型別以及 foreach 陳述式 (Statement) 中反覆運算變數的型別相容。這個強型別可確保系統能夠在編譯時期攔截到型別錯誤,以在使用者發生這類錯誤之前予以更正。
為了示範這些型別關聯性,在下面的大部分範例中,所有變數都是使用明確型別。最後一個範例則會使用 var 進行隱含型別處理,以證明相同的準則仍適用於隱含型別。
未轉換來源資料的查詢
下圖顯示未執行資料轉換的 LINQ to Objects 查詢作業。這個來源包含字串序列,而查詢輸出也會是字串序列。
資料來源的型別引數會決定範圍變數的型別。
所選取物件的型別會決定查詢變數的型別。這裡的 name 是字串。因此,查詢變數是 IEnumerable<string>。
foreach 陳述式中會逐一查看查詢變數。因為查詢變數是字串序列,所以反覆運算變數也會是字串。
轉換來源資料的查詢
下圖顯示執行簡單資料轉換的 LINQ to SQL 查詢作業。這個查詢會採用 Customer 物件的序列做為輸入,而且只會選取結果中的 Name 屬性。因為 Name 是字串,所以查詢會產生字串序列做為輸出。
資料來源的型別引數會決定範圍變數的型別。
select 陳述式會傳回 Name 屬性,而不是整個 Customer 物件。因為 Name 是字串,所以 custNameQuery 的型別引數是 string,而不是 Customer。
因為 custNameQuery 是字串序列,所以 foreach 迴圈 (Loop) 的反覆運算變數也必須是 string。
下圖顯示稍微複雜一點的轉換。select 陳述式會傳回匿名型別,這個匿名型別只會使用原始 Customer 物件的兩個成員做為屬性。
資料來源的型別引數一律會是查詢中範圍變數的型別。
因為 select 陳述式會產生匿名型別,所以必須使用 var 對查詢變數進行隱含型別處理。
因為查詢變數的型別是隱含的,所以 foreach 迴圈中的反覆運算變數也必須是隱含的。
讓編譯器推斷型別資訊
雖然您應該要知道查詢作業中的型別關聯性,但是也可以選擇讓編譯器幫您完成這一切工作。關鍵字 var 可以用於查詢作業中的任何區域變數。下圖完全等於先前討論過的範例 2。唯一的差異在於編譯器會提供查詢作業中之每個變數的強型別:
如需 var 的詳細資訊,請參閱 隱含型別區域變數 (C# 程式設計手冊)。