Đây có phải là lỗ hổng trong cơ chế truyền từ điển hay trong suy nghĩ của tôi rằng điều này nên được cho phép?
Trong suy nghĩ của bạn. Bạn đang mong rằng các từ điển phải là covariant trong các chuyển đổi của chúng. Họ không, vì lý do sau đây. Giả sử họ, và suy ra những gì có thể đi sai:
Dictionary<int, List<string>> castMeDict =
new Dictionary<int, List<string>>();
Dictionary<int, IEnumerable<string>> getFromDict =
(Dictionary<int, IEnumerable<string>>)castMeDict;
castMeDict[123] = new List<string>();
IEnumerable<string> strings = getFromDict[123]; // No problem!
getFromDict[123] = new string[] { "hello" }; // Big problem!
Một mảng của chuỗi là mui trần để IEnumerable<string>
nhưng không List<string>
. Bạn chỉ cần đặt một cái gì đó là không một danh sách chuỗi vào từ điển chỉ có thể lấy danh sách chuỗi.
Trong C# loại generic có thể hiệp biến hoặc contravariant nếu tất cả các điều kiện sau đây được đáp ứng:
- Bạn đang sử dụng C# 4 trở lên.
- Loại chung chung khác nhau là giao diện hoặc đại biểu.
- Phương sai được chứng minh là an toàn. (Thông số C# mô tả các quy tắc chúng tôi sử dụng để xác định độ an toàn phương sai. C# 4.0 Phiên bản tệp doc có thể được tải xuống [here]. Xem phần 23.5.)
- Các đối số kiểu khác nhau là tất cả các loại tham chiếu.
- Loại đã được đánh dấu cụ thể là an toàn cho phương sai.
Hầu hết các điều kiện này không được đáp ứng cho từ điển - nó không phải là giao diện hoặc đại biểu, không an toàn, và loại không được đánh dấu là an toàn cho phương sai. Vì vậy, không có phương sai cho từ điển.
IEnumerable<T>
ngược lại không đáp ứng tất cả các điều kiện đó. Bạn có thể chuyển đổi IEnumerable<string>
để IEnumerable<object>
trong C# 4.
Nếu đối tượng phương sai bạn quan tâm, xem xét đọc hai chục bài viết của tôi về đề tài này:
http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/
Nguồn
2011-12-19 20:45:07
Xem: [Hiểu hiệp biến và contravariant giao diện trong C# ] (http://stackoverflow.com/questions/2719954/understanding-covariant-and-contravariant-interfaces-in-c-sharp) – Magnus
Cảm ơn mọi người. Xin lỗi, tôi đã kiểm tra bản sao nhưng có một chút khó khăn khi khái quát trước, sau đó tìm kiếm tất cả các phiên bản cụ thể có thể trùng lặp mà không biết câu trả lời. – user420667