主要特點
- 一對多對應(One-to-Many):一個鍵(Key)可以對應到多個值(Collection of values),與 ToDictionary(一對一)不同
- 立即執行(Eager Execution):呼叫 ToLookup() 時會立即計算並產生結果,這點跟 GroupBy()延遲執行 (Deffered Execution) 不同
- 唯讀結構:產生的 ILookup 是唯讀的,無法修改
- 安全存取:如果用 Key 去取值,就算該 Key 不存在,它也會回傳一個空的集合而不是丟出例外錯誤(KeyNotFoundException)
簡易範例
namespace ToLookupSample
{
internal class Program
{
static void Main(string[] args)
{
var books = new List<Book>
{
new Book { Title = "C# 實戰", Category = "CSharp", PublishYear = 2025 },
new Book { Title = "設計模式", Category = "CSharp", PublishYear = 2023 },
new Book { Title = "MS SQL TSQL 學習手冊", Category = "SQL", PublishYear = 2020 },
new Book { Title = "MS SQL 效能調校", Category = "SQL", PublishYear = 2025 },
new Book { Title = "MS SQL 索引深入淺出", Category = "SQL", PublishYear = 2025 },
new Book { Title = "世界歷史", Category = "History", PublishYear = 1981 }
};
// 1. 建立 ILookup:以 Category 為 Key
ILookup<string, Book> bookLookup = books.ToLookup(b => b.Category);
// 2. 透過索引子 [Key] 查詢存在的書籍分類
IEnumerable<Book> sql = bookLookup["SQL"];
Console.WriteLine($"SQL 書籍:{sql.Count()}");
foreach (Book book in sql)
Console.WriteLine($" ----- {book.Title}");
// 3. 查詢不存在的書籍分類:回傳空集合,不會拋出 Exception
IEnumerable<Book> ai = bookLookup["AI"];
Console.WriteLine($"是否有 AI 分類書籍:{ai.Any()}");
// 4. 檢查某個 Key 是否存在
bool hasHistory = bookLookup.Contains("History");
Console.WriteLine($"是否有 History 分類書籍:{hasHistory}");
// 5. 忽略大小寫
ILookup<string, string> books4OrdinalIgnoreCase = books.ToLookup(
keySelector: b => b.Category,
elementSelector: b => b.Title,
comparer: StringComparer.OrdinalIgnoreCase // 忽略大小寫
);
IEnumerable<string> csharp = books4OrdinalIgnoreCase["csharp"];
Console.WriteLine($"C# 書籍 - 不區分大小寫");
foreach (string title in csharp)
Console.WriteLine($" ----- {title}");
// 6. Key 使用 ValueTuple (Category, PublishYear) 作為複合 Key
var booksValueTuple = books.ToLookup(b => (
Category: b.Category,
Year: b.PublishYear
));
var targetKey = ("SQL", 2025);
var matchedBooks = booksValueTuple[targetKey].ToList();
Console.WriteLine($"2005 出版 SQL 書籍 - 複合 Key");
foreach (Book book in matchedBooks)
Console.WriteLine($" ----- {book.Title}");
}
}
public class Book
{
public string Title { get; set; }
public string Category { get; set; }
public int PublishYear { get; set; }
}
}
















