若要有效地撰寫查詢,您應該瞭解完整查詢作業中變數的類型如何彼此相關。 如果您了解這些關聯性,您將更容易理解檔中的 LINQ 範例和程式代碼範例。 此外,您將瞭解使用 var
隱含類型變數時會發生什麼情況。
LINQ 查詢作業在數據源、查詢本身和查詢執行中具有強型別。 查詢中的變數類型必須與數據源中的項目類型以及語句中的 foreach
反覆專案變數類型相容。 這種強類型檢查可確保在編譯階段檢測到類型錯誤,以便在使用者遇到錯誤之前加以更正。
為了示範這些類型關聯性,後續大部分範例都會對所有變數使用明確輸入。 最後一個範例顯示,即使使用隱含型別,您還是能夠應用相同的原則。
未轉換源數據的查詢
下圖顯示不會對數據執行任何轉換的LINQ to Objects查詢作業。 來源包含一連串的字串,而查詢輸出也是一連串的字串。
- 數據源的 type 自變數會決定範圍變數的類型。
- 選取之物件的型別會決定查詢變數的類型。 以下是
name
字串。 因此,查詢變數是IEnumerable<string>
。 - 查詢變數會在
foreach
語句中被遍歷。 因為查詢變數是一連串字串,因此反覆運算變數也是字串。
轉換源數據的查詢
下圖顯示對數據執行簡單轉換的 LINQ to SQL 查詢作業。 查詢會接受一連串的 Customer
物件做為輸入,僅選取結果中的 Name
屬性。 因為 Name
是字串,因此查詢會產生一連串字串做為輸出。
- 數據源的 type 自變數會決定範圍變數的類型。
- 語句
select
傳回Name
屬性,而不是完整的Customer
物件。 因為Name
是字串,因此的型別自變數custNameQuery
為string
,而不是Customer
。 - 因為
custNameQuery
是字串序列,循環foreach
的反覆項目變數也必須是string
。
下圖顯示稍微複雜一點的轉換。 語句 select
會傳回匿名型別,只擷取原始 Customer
物件的兩個成員。
- 數據源的類型自變數一律是查詢中範圍變數的類型。
- 由於
select
語句產生匿名型別,因此查詢變數必須使用隱式類型var
。 - 因為查詢變數的類型是隱含的,因此迴圈中的
foreach
反覆專案變數也必須是隱含的。
讓編譯程式推斷類型資訊
雖然您應該了解查詢作業中的類型關聯性,但您可以選擇讓編譯程式為您執行所有工作。 關鍵詞 var 可用於查詢作業中的任何局部變數。 下圖與稍早討論的範例數位 2 類似。 不過,編譯程式會提供查詢作業中每個變數的強型別。
LINQ 和泛型 (C#)
LINQ 查詢是以泛型類型為基礎。 開始撰寫查詢之前,您不需要深入瞭解泛型。 不過,您可能想要瞭解兩個基本概念:
- 當您建立泛型集合類別 List<T>的實例時,您會將 「T」 取代為清單將儲存的物件類型。 例如,字串清單會以
List<string>
表示,而物件清單Customer
會以List<Customer>
表示。 泛型清單是強型別,而且相較於將元素儲存為 Object 的集合,泛型清單提供了許多優勢。 如果您嘗試將 加入Customer
至List<string>
,您會在編譯時期收到錯誤。 使用泛型集合很容易,因為您不需要執行運行時間類型轉換。 -
IEnumerable<T> 是介面,可讓泛型集合類別使用
foreach
語句來列舉。 泛型集合類別支援 IEnumerable<T>,就像非泛型集合類別(例如 ArrayList)支援 IEnumerable 一樣。
如需泛型的詳細資訊,請參閱 泛型。
LINQ 查詢中的 IEnumerable<T> 變數
LINQ 查詢變數的類型是 IEnumerable<T> 或衍生類型,例如 IQueryable<T>。 當您看到類型為 IEnumerable<Customer>
的查詢變數時,它只是表示查詢在執行時,會產生零個或多個 Customer
物件的序列。
IEnumerable<Customer> customerQuery = from cust in customers
where cust.City == "London"
select cust;
foreach (Customer customer in customerQuery)
{
Console.WriteLine($"{customer.LastName}, {customer.FirstName}");
}
讓編譯程式處理泛型類型宣告
如果您想要的話,您可以使用 var 關鍵詞來避免泛型語法。
var
關鍵詞會指示編譯程式藉由查看 子句中指定的from
數據源來推斷查詢變數的類型。 下列範例會產生與上一個範例相同的已編譯程序代碼:
var customerQuery2 = from cust in customers
where cust.City == "London"
select cust;
foreach(var customer in customerQuery2)
{
Console.WriteLine($"{customer.LastName}, {customer.FirstName}");
}
當需要明確指定變數的類型為巢狀泛型類型,比如群組查詢所產生的類型,或者當變數類型顯然不需要特別強調時,var
這個關鍵字非常有用。 一般而言,我們建議您使用 var
時,須瞭解它可能會使其他人更難閱讀您的程序代碼。 如需詳細資訊,請參閱隱含型別區域變數。