首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# Dictionary 泛型集合完整操作範例教學

     編輯:關於C#

前言

Dictionary<TKey, TValue> 是 C# 中最常用的泛型集合之一,提供鍵值對(Key-Value Pair)的快速查找、新增、刪除與列舉功能。底層採用雜湊表實現,查找與插入的平均時間複雜度為 O(1)。本文透過一個完整的 Console 應用程式範例,詳細示範 Dictionary 的核心操作,包含新增、查詢、修改、移除、例外處理、TryGetValue、ContainsKey、列舉 Keys/Values、KeyValuePair 等實用技巧。

完整程式碼範例

using System;
using System.Collections.Generic;

namespace DictionaryDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // 1. 建立 Dictionary
            var openWith = new Dictionary();

            // 2. 新增元素(鍵不可重複,值可重複)
            openWith.Add("txt", "notepad.exe");
            openWith.Add("bmp", "paint.exe");
            openWith.Add("dib", "paint.exe");  // 值重複沒問題
            openWith.Add("rtf", "wordpad.exe");

            Console.WriteLine("=== 初始集合 ===");
            PrintDictionary(openWith);

            // 3. 嘗試新增重複鍵 → 會拋出 ArgumentException
            try
            {
                openWith.Add("txt", "winword.exe");
            }
            catch (ArgumentException ex)
            {
                Console.WriteLine($"\n[例外處理] {ex.Message}");
                // 輸出:An element with Key = "txt" already exists.
            }

            // 4. 使用索引子 讀取/修改 值
            Console.WriteLine($"\n[索引子讀取] rtf 對應值:{openWith["rtf"]}");
            openWith["rtf"] = "winword.exe";  // 修改現有鍵的值
            Console.WriteLine($"[索引子修改] rtf 新值:{openWith["rtf"]}");

            // 5. 索引子新增不存在的鍵
            openWith["doc"] = "winword.exe";  // 相當於 Add
            Console.WriteLine($"[索引子新增] doc:{openWith["doc"]}");

            // 6. 讀取不存在的鍵 → 拋出 KeyNotFoundException
            try
            {
                Console.WriteLine(openWith["tif"]);
            }
            catch (KeyNotFoundException ex)
            {
                Console.WriteLine($"\n[例外處理] {ex.Message}");
            }

            // 7. 推薦:使用 TryGetValue 避免例外(效能更好)
            string value = "";
            if (openWith.TryGetValue("tif", out value))
                Console.WriteLine($"[TryGetValue] tif = {value}");
            else
                Console.WriteLine("[TryGetValue] 找不到鍵 'tif'");

            // 8. ContainsKey:新增前先檢查
            if (!openWith.ContainsKey("ht"))
            {
                openWith.Add("ht", "hypertrm.exe");
                Console.WriteLine($"\n[ContainsKey] 新增 ht:{openWith["ht"]}");
            }

            // 9. 列舉所有 KeyValuePair
            Console.WriteLine("\n=== 列舉 KeyValuePair ===");
            foreach (var kvp in openWith)
            {
                Console.WriteLine($"Key = {kvp.Key}, Value = {kvp.Value}");
            }

            // 10. 只列舉 Values
            Console.WriteLine("\n=== 列舉 Values ===");
            foreach (string s in openWith.Values)
                Console.WriteLine($"Value = {s}");

            // 11. 只列舉 Keys
            Console.WriteLine("\n=== 列舉 Keys ===");
            foreach (string s in openWith.Keys)
                Console.WriteLine($"Key = {s}");

            // 12. 移除鍵值對
            Console.WriteLine("\n=== 移除 doc ===");
            openWith.Remove("doc");
            if (!openWith.ContainsKey("doc"))
                Console.WriteLine("Key \"doc\" 已成功移除。");

            Console.WriteLine("\n=== 最終集合 ===");
            PrintDictionary(openWith);

            Console.ReadKey();
        }

        static void PrintDictionary(Dictionary dict)
        {
            foreach (var kvp in dict)
                Console.WriteLine($"  {kvp.Key} → {kvp.Value}");
        }
    }
}

核心方法與屬性總結表

方法/屬性用途備註
Add(key, value)新增鍵值對鍵重複拋出 ArgumentException
Remove(key)移除指定鍵回傳 bool,表示是否成功移除
TryGetValue(key, out value)嘗試取得值推薦,避免例外,效能最佳
ContainsKey(key)檢查鍵是否存在O(1),新增前建議先檢查
ContainsValue(value)檢查值是否存在O(n),需遍歷
Clear()清空所有元素
Count元素數量屬性
Keys取得鍵集合回傳 KeyCollection
Values取得值集合回傳 ValueCollection
this[key] (索引子)讀寫值讀取不存在鍵拋出例外;寫入不存在鍵等同 Add

進階技巧與注意事項

1. 自訂類別作為 Key 時需覆寫 Equals 與 GetHashCode

public class Person
{
    public string Id { get; set; }
    public string Name { get; set; }

    public override bool Equals(object obj)
    {
        return obj is Person other && Id == other.Id;
    }

    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }
}

若未正確實作,Dictionary 將無法正確判斷鍵是否重複。

2. 線程安全

Dictionary<TKey, TValue> 非線程安全。多線程環境下請使用 ConcurrentDictionary<TKey, TValue>(位於 System.Collections.Concurrent),提供無鎖或細粒度鎖的執行緒安全操作。

3. 初始化語法糖 (C# 6+)

var dict = new Dictionary
{
    ["apple"] = 1,
    ["banana"] = 2,
    ["orange"] = 3
};

4. 避免在 foreach 中修改集合

在 foreach 迴圈中呼叫 Add 或 Remove 會拋出 InvalidOperationException。需先蒐集要修改的鍵,迴圈結束後再操作。

總結

Dictionary<TKey, TValue> 是高效能鍵值對集合的首選。掌握 TryGetValue、ContainsKey、索引子讀寫、安全列舉等核心操作,能讓你在實務開發中游刃有餘。記住:鍵不可重複、值可重複、非線程安全、自訂 Key 需正確實作雜湊邏輯。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved