2011-12-09 32 views
22

Tôi đang cố gắng giải thích chi tiết cho một số thực sự WeakKeyedDictionary<,> cho C# ... nhưng tôi đang gặp khó khăn.Có thể tạo một từ điển có khóa yếu trong C# không?

Tôi nhận ra đây là một nhiệm vụ không tầm thường, nhưng dường như không có khả năng khai báo WeakKeyedKeyValuePair<,> (trong đó GC chỉ tuân theo tham chiếu giá trị nếu khóa đó có thể truy cập được).

Có hai vấn đề chính tôi thấy:

  1. Mỗi thực hiện cho đến nay tôi đã nhìn thấy không cắt các giá trị sau khi các phím đã được thu thập. Hãy nghĩ về điều đó - một trong những lý do chính để sử dụng một từ điển là ngăn chặn các giá trị đó được giữ lại (không chỉ là các phím!) Vì chúng không thể truy cập được, nhưng ở đây chúng được trỏ đến bằng các tham chiếu mạnh mẽ.

    Có, thêm/xóa khỏi từ điển đủ và cuối cùng chúng sẽ được thay thế, nhưng nếu bạn không làm gì?

  2. Nếu không có giả thuyết WeakKeyedKeyValuePair<,> (hoặc phương tiện khác để yêu cầu GC chỉ đánh dấu giá trị nếu khóa có thể truy cập được), bất kỳ giá trị nào liên quan đến khóa đó sẽ không bao giờ được thu thập. Đây là một vấn đề khi lưu trữ các giá trị tùy ý.

Bài toán 1 có thể được giải quyết theo cách khá lý tưởng/hack: sử dụng GC Thông báo đợi GC hoàn chỉnh, sau đó đi và cắt từ điển trong chuỗi khác. Điều này tôi bán ok với.

Nhưng vấn đề 2 khiến tôi bối rối. Tôi nhận ra điều này có thể dễ dàng chống lại bởi một "vì vậy đừng làm điều đó", nhưng nó đã cho tôi tự hỏi - là vấn đề này thậm chí có thể giải quyết?

Trả lời

28

Hãy xem qua số ConditionalWeakTable<TKey, TValue> Class.

Cho phép trình biên dịch tự động đính kèm trường đối tượng vào đối tượng được quản lý.

Đây thực chất là từ điển mà cả khóa và giá trị là WeakReference và giá trị được giữ nguyên miễn là khóa còn hoạt động.

Lưu ý! Lớp này không sử dụng GetHashCodeEquals để so sánh bình đẳng, nó sử dụng ReferenceEquals.

+0

Tìm tốt, hấp dẫn nhất! Làm thế nào nó được thực hiện tôi tự hỏi? Nếu không biết vấn đề này trở thành "có thể tạo ra một WeakValuedDictionary <,> thực sự" hay không. Tôi sẽ đào vào phản xạ và xem nếu tôi có thể tìm ra nó ... – Mania

+3

Thật xấu hổ, nó xuất hiện nó phụ thuộc vào một nội bộ .NET-ma thuật "DependentHandle" cho nó thực hiện .. ngoài ra nó bỏ qua .GetHashCode và .Equals , làm cho nó trở thành một từ điển không đạt chuẩn ở mức tốt nhất: (Ngoài ra không có quyền truy cập vào DependentHandle, vấn đề bây giờ đã chuyển sang định nghĩa WeakValuedDictionary <,>. Tôi cho rằng điều này có thể gần như có thể .. – Mania

+7

@Mania DependentHandle là thực hiện CLR của [ephemerons] (http://en.wikipedia.org/wiki/Ephemeron) mà không thể thực hiện nếu không có sự hợp tác của GC. Nó phải được công khai như GCHandle. Nếu bạn không nhớ sự phản chiếu, bạn có thể biến cái tĩnh CLR phương pháp thành các đại biểu và thực hiện DependentHandle của riêng bạn và WeakValuedDictionary Hãy cẩn thận để nghiên cứu các nguồn tài liệu tham khảo. NET (được công khai), hoặc sử dụng một số decompiler, bởi vì nó có conditio cuộc đua khó khăn ns. – Zarat

Các vấn đề liên quan