Cơ bản: Dictionary<TKey, TValue>
- Collection generic lưu trữ cặp Key/Value.
- Key: không được null, phải duy nhất (unique).
- Value: có thể null, có thể trùng lặp.
- Truy xuất:
O(1)trung bình nhờ hash table.
Cập nhật giá trị
Cú pháp đơn giản nhất:
myDictionary[myKey] = newValue;
Lưu ý: Nếu key không tồn tại, câu lệnh này sẽ thêm mới cặp key/value. Nếu key đã tồn tại, nó sẽ ghi đè value cũ.
Ví dụ cơ bản
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// Khởi tạo Dictionary với collection initializer
var students = new Dictionary<int, string>
{
{ 1, "John" },
{ 2, "Mrk" }, // Tình hình chính tả
{ 3, "Bill" }
};
Console.WriteLine($"Trước: ID 2 = {students[2]}"); // Mrk
// Cập nhật value cho key = 2
students[2] = "Mark";
Console.WriteLine($"Sau: ID 2 = {students[2]}"); // Mark
}
}
Kết quả
Trước: ID 2 = Mrk Sau: ID 2 = Mark
Các phương pháp an toàn hơn
1. TryGetValue + gán (không throw nếu key không tồn tại)
if (students.TryGetValue(2, out var currentName))
{
students[2] = "Mark";
Console.WriteLine($"Đã cập nhật từ '{currentName}' thành 'Mark'");
}
else
{
Console.WriteLine("Không tìm thấy key 2");
}
2. ContainsKey check trước
if (students.ContainsKey(2))
{
students[2] = "Mark";
}
3. Dictionary.GetValueOrDefault (C# 7+ / .NET Core 2.0+)
// Lấy value hoặc default nếu không có key
var name = students.GetValueOrDefault(99, "Unknown"); // "Unknown"
Cập nhật phức tạp: Value là object/reference type
class Student
{
public string Name { get; set; }
public int Age { get; set; }
}
var dict = new Dictionary<int, Student>();
dict[1] = new Student { Name = "John", Age = 20 };
// Cách 1: Thay thế toàn bộ object
dict[1] = new Student { Name = "Jane", Age = 21 };
// Cách 2: Cập nhật property của object hiện có (nếu reference type)
if (dict.TryGetValue(1, out var student))
{
student.Name = "Jane"; // Mutate object in-place
student.Age = 21;
// dict[1] vẫn trỏ đến cùng object, không cần gán lại
}
Thread Safety
⚠️ Dictionary KHÔNG thread-safe. Nếu multi-thread đọc/ghi đồng thời → dùng
ConcurrentDictionary<TKey, TValue> (namespace System.Collections.Concurrent).
using System.Collections.Concurrent;
var safeDict = new ConcurrentDictionary<int, string>();
// Cập nhật atomic (thread-safe)
safeDict.AddOrUpdate(2, "Mark", (key, oldValue) => "Mark");
// Hoặc
safeDict[2] = "Mark"; // Cũng thread-safe cho single operation
Các operation liên quan
| Phép toán | Cú pháp | Hành vi |
|---|---|---|
| Thêm/Cập nhật | dict[key] = value | Thêm mới nếu key chưa có, ghi đè nếu đã có |
| Thêm (báo lỗi nếu trùng) | dict.Add(key, value) | Throw ArgumentException nếu key tồn tại |
| Thêm nếu chưa có | dict.TryAdd(key, value) | Trả về bool, không throw |
| Cập nhật có điều kiện | dict.TryUpdate(key, newVal, oldVal) | Chỉ cập nhật nếu value hiện tại = oldVal (ConcurrentDictionary) |
| Xóa | dict.Remove(key) | Trả về bool thành công |
| Xóa có điều kiện | dict.Remove(key, out value) | Lấy value trước khi xóa |