共用方式為


LINQ 查詢作業中的類型關聯性 (C#)

若要有效地撰寫查詢,您應該瞭解完整查詢作業中變數的類型如何彼此相關。 如果您了解這些關聯性,您將更容易理解檔中的 LINQ 範例和程式代碼範例。 此外,您將瞭解使用 var 隱含類型變數時會發生什麼情況。

LINQ 查詢作業在數據源、查詢本身和查詢執行中具有強型別。 查詢中的變數類型必須與數據源中的項目類型以及語句中的 foreach 反覆專案變數類型相容。 這種強類型檢查可確保在編譯階段檢測到類型錯誤,以便在使用者遇到錯誤之前加以更正。

為了示範這些類型關聯性,後續大部分範例都會對所有變數使用明確輸入。 最後一個範例顯示,即使使用隱含型別,您還是能夠應用相同的原則。

未轉換源數據的查詢

下圖顯示不會對數據執行任何轉換的LINQ to Objects查詢作業。 來源包含一連串的字串,而查詢輸出也是一連串的字串。

顯示 LINQ 查詢中數據類型關聯性圖表。

  1. 數據源的 type 自變數會決定範圍變數的類型。
  2. 選取之物件的型別會決定查詢變數的類型。 以下是 name 字串。 因此,查詢變數是 IEnumerable<string>
  3. 查詢變數會在 foreach 語句中被遍歷。 因為查詢變數是一連串字串,因此反覆運算變數也是字串。

轉換源數據的查詢

下圖顯示對數據執行簡單轉換的 LINQ to SQL 查詢作業。 查詢會接受一連串的 Customer 物件做為輸入,僅選取結果中的 Name 屬性。 因為 Name 是字串,因此查詢會產生一連串字串做為輸出。

顯示轉換數據類型之查詢的圖表。

  1. 數據源的 type 自變數會決定範圍變數的類型。
  2. 語句 select 傳回 Name 屬性,而不是完整的 Customer 物件。 因為 Name 是字串,因此的型別自變數 custNameQuerystring,而不是 Customer
  3. 因為 custNameQuery 是字串序列,循環 foreach 的反覆項目變數也必須是 string

下圖顯示稍微複雜一點的轉換。 語句 select 會傳回匿名型別,只擷取原始 Customer 物件的兩個成員。

此圖顯示轉換數據類型更複雜的查詢。

  1. 數據源的類型自變數一律是查詢中範圍變數的類型。
  2. 由於select語句產生匿名型別,因此查詢變數必須使用隱式類型var
  3. 因為查詢變數的類型是隱含的,因此迴圈中的 foreach 反覆專案變數也必須是隱含的。

讓編譯程式推斷類型資訊

雖然您應該了解查詢作業中的類型關聯性,但您可以選擇讓編譯程式為您執行所有工作。 關鍵詞 var 可用於查詢作業中的任何局部變數。 下圖與稍早討論的範例數位 2 類似。 不過,編譯程式會提供查詢作業中每個變數的強型別。

顯示具有隱含型別之類型流程的圖表。

LINQ 和泛型 (C#)

LINQ 查詢是以泛型類型為基礎。 開始撰寫查詢之前,您不需要深入瞭解泛型。 不過,您可能想要瞭解兩個基本概念:

  1. 當您建立泛型集合類別 List<T>的實例時,您會將 「T」 取代為清單將儲存的物件類型。 例如,字串清單會以List<string>表示,而物件清單Customer會以List<Customer>表示。 泛型清單是強型別,而且相較於將元素儲存為 Object 的集合,泛型清單提供了許多優勢。 如果您嘗試將 加入 CustomerList<string>,您會在編譯時期收到錯誤。 使用泛型集合很容易,因為您不需要執行運行時間類型轉換。
  2. 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 時,須瞭解它可能會使其他人更難閱讀您的程序代碼。 如需詳細資訊,請參閱隱含型別區域變數