Chciałem stworzyć obiekt podobny do Słownika i pomyślałem, że właściwym sposobem będzie implementacja interfejsu IDictionary<K,V>
i użycie kompozycji do uwzględnienia podstawowego słownika. I zaczęło się poniżej (K
= string
, V
= int
)Dlaczego słownik C# nie implementuje całego IDictionary?
public class DictionaryLikeObject : IDictionary<string,int> {
Dictionary<string,int> _backingDictionary = new Dictionary<string,int>();
}
Następnie użyłem Visual Studio "zaimplementować interfejs" zdolność odgałęzienie wszystkie metody tytułowych że będę potrzebował.
Trzy sposoby IDictionary
nie wydają się istnieć w Dictionary
:
void Add(KeyValuePair<string, int> item);
void CopyTo(KeyValuePair<string, int>[] array, int arrayIndex);
bool Remove(KeyValuePair<string, int> item);
the Microsoft documentation jednak wyraźnie wskazuje, że Dictionary
realizuje IDictionary
. Tak więc oczekiwałbym, że te trzy metody będą dostępne. Aby skopiować z dokumentacją definicję 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
Te trzy brakujące metod, jak sądzę, można znaleźć w ICollection<>
. Ale tak samo są inne metody, takie jak Clear()
, które ma Dictionary
.
Pytanie 1: Jak można C# uciec bez wdrożenia tych trzech i dlaczego tak się dzieje? Podejrzeń, że jest to błąd kompilatora (dla mojego rozumowania, patrz poniżej). Pytanie 2: Alternatywnie, czego mi brakuje?
Oto dlaczego myślę, że może to być błąd kompilatora. Zbadać następujący kod:
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
Sposób void Add(KeyValuePair<string, int> item)
nie wydaje się być w Dictionary<string,int>
(ponieważ nie skompilować), ale jest w IDictionary<string,int>
i jakoś kompilator ma właściwie znaleźć implementacji. Pytanie 3: Co się dzieje?
Należy pamiętać, że dokumentacja Microsoft dla Dictionary<K,V>
nie określa tych trzech metod.
Wreszcie w mojej rzeczywistej realizacji, skończyło się za pomocą
IDictionary<string,int> _backingDictionary = new Dictionary<string,int>();
zamiast
Dictionary<string,int> _backingDictionary = new Dictionary<string,int>();
tak, że wszystkie trzy metody mogą łatwo pracować.
To było dokładnie moje pierwsze przypuszczenie. Czy wiesz, dlaczego nie jest to określone w dokumentacji MSDN? Dlaczego ukryli te metody? –
@the_drow, nie jestem pewien, dlaczego nie dokonują tego rozróżnienia w dokumentacji, ani nie jestem w 100% pewien, dlaczego dokonali wyboru. Moim pierwszym instynktem dla tych drugich jest to, że chcieli zapewnić pojedyncze przeciążenie domyślnie przez Add. – JaredPar
@the_drow: Jest to faktycznie określone w dokumentacji MSDN. Trzeba tylko przewinąć w dół do "Jawnych implementacji interfejsu". – Daniel