2011-08-26 23 views
25

Tôi muốn tạo một đối tượng giống như từ điển và nghĩ cách chính xác sẽ là triển khai giao diện IDictionary<K,V> và sử dụng bố cục để bao gồm từ điển cơ bản. Tôi bắt đầu với bên dưới (K = string, V = int)Tại sao từ điển C# không thực hiện tất cả IDictionary?

public class DictionaryLikeObject : IDictionary<string,int> { 
    Dictionary<string,int> _backingDictionary = new Dictionary<string,int>(); 
} 

Sau đó, tôi sử dụng "Thực hiện giao diện" khả năng của Visual Studio để còn sơ khai ra tất cả các phương pháp bìa rằng tôi sẽ cần.

Ba phương pháp IDictionary dường như không tồn tại trong Dictionary:

void Add(KeyValuePair<string, int> item); 
void CopyTo(KeyValuePair<string, int>[] array, int arrayIndex); 
bool Remove(KeyValuePair<string, int> item); 

Tuy the Microsoft documentation cho thấy rõ ràng rằng Dictionary thực hiện IDictionary. Vì vậy, tôi đã có thể mong đợi ba phương pháp này để có sẵn. Để sao chép từ các tài liệu, định nghĩa về Dictionary<K,V>

[SerializableAttribute] 
[ComVisibleAttribute(false)] 
public class Dictionary<K, V> : IDictionary<K, V>, 
ICollection<KeyValuePair<K, V>>, IEnumerable<KeyValuePair<K, V>>, 
IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback 

Ba phương pháp còn thiếu, tôi tin rằng, được tìm thấy trong ICollection<>. Nhưng các phương pháp khác như Clear() rằng Dictionary không có.

Câu hỏi 1: Làm thế nào để C# có thể lấy đi mà không thực hiện ba điều này và tại sao lại như vậy? Tôi nghi ngờ đây là một lỗi trình biên dịch (vì lý do của tôi, xem dưới đây). Câu hỏi 2: Ngoài ra, tôi còn thiếu gì?

Đây là lý do tại sao tôi nghĩ rằng đó có thể là lỗi trình biên dịch. Kiểm tra các đoạn mã sau:

Dictionary<string, int> dictionary1 = new Dictionary<string, int>(); 
IDictionary<string, int> dictionary2 = new Dictionary<string, int>(); 
KeyValuePair<string, int> item = new KeyValuePair<string, int>("test", 1); 
//dictionary1.Add(item); // compile error: No overload for method 'Add' takes 1 argument 
dictionary2.Add(item); // works like a charm 
Debug.WriteLine(@"dictionary2[""test""] = {0}", dictionary2["test"]); // outputs: dictionary2["test"] = 1 

Phương pháp này void Add(KeyValuePair<string, int> item) dường như không có trong Dictionary<string,int> (vì nó không biên dịch), nhưng nó là trong IDictionary<string,int>, và bằng cách nào đó trình biên dịch không tìm đúng một thực hiện của nó. Câu hỏi 3: Điều gì đang xảy ra?

Lưu ý rằng tài liệu của Microsoft dành cho Dictionary<K,V> không chỉ định ba phương thức này.

Cuối cùng, trong việc thực hiện thực tế của tôi, tôi đã kết thúc bằng

IDictionary<string,int> _backingDictionary = new Dictionary<string,int>(); 

thay vì

Dictionary<string,int> _backingDictionary = new Dictionary<string,int>(); 

để tất cả ba phương pháp có thể dễ dàng làm việc.

Trả lời

44

Dictionary<TKey, TValue> thực hiện các phương pháp này, nó chỉ làm như vậy một cách rõ ràng. Do đó bạn phải truy cập thông qua giao diện IDictionary<TKey, TValue>.

Dictionary<string, string> map = ...; 
KeyValuePair<string, string> pair = ...; 
map.Add(pair); // Compilation Error 
((IDictionary<string, string>)map).Add(pair); // Works 

Làm việc rõ ràng bằng cách xác định phương thức giao diện cụ thể thực hiện tại điểm định nghĩa. Ví dụ:

interface IFoo { 
    void Method(); 
} 

class C1 : IFoo { 
    // Implicitly implements IFoo.Method 
    public void Method() { } 
} 

class C2 : IFoo { 
    // Explicitly implements IFoo.Method 
    void IFoo.Method() { } 
} 
+1

Đó chính xác là dự đoán đầu tiên của tôi. Bạn có biết tại sao điều này không được chỉ định trong tài liệu MSDN? Ngoài ra, tại sao họ ẩn những phương pháp đó? –

+0

@ the_drow, tôi không chắc chắn lý do tại sao họ không phân biệt trong tài liệu đó và tôi chắc chắn 100% lý do tại sao họ chọn lựa. Bản năng đầu tiên của tôi cho bản năng thứ hai là họ muốn cung cấp một tình trạng quá tải của Add theo mặc định. – JaredPar

+6

@ the_drow: Nó thực sự được chỉ định trong tài liệu MSDN. Bạn chỉ cần cuộn xuống "Triển khai Giao diện Rõ ràng" – Daniel

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