recorrer - ¿Por qué el diccionario C#no implementa todo IDictionary?
obtener valor de un diccionario c# (1)
Quería crear un objeto similar a un Diccionario y pensé que la forma correcta sería implementar la IDictionary<K,V>
y usar la composición para incluir el diccionario subyacente. Comencé con lo siguiente ( K
= string
, V
= int
)
public class DictionaryLikeObject : IDictionary<string,int> {
Dictionary<string,int> _backingDictionary = new Dictionary<string,int>();
}
Luego usé la capacidad de "Implementar interfaz" de Visual Studio para eliminar todos los métodos de cobertura que necesitaría.
Tres métodos de IDictionary
no parecen existir en el Dictionary
:
void Add(KeyValuePair<string, int> item);
void CopyTo(KeyValuePair<string, int>[] array, int arrayIndex);
bool Remove(KeyValuePair<string, int> item);
Sin embargo, la documentación de Microsoft indica claramente que el Dictionary
implementa IDictionary
. Así que habría esperado que estos tres métodos estuvieran disponibles. Para copiar de la documentación, la definición de 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
Estos tres métodos faltantes, creo, se encuentran en ICollection<>
. Pero también lo son otros métodos como Clear()
que tiene el Dictionary
.
Pregunta 1: ¿Cómo puede C # escapar sin implementar estos tres, y por qué es así? Sospecho que esto es un error del compilador (para mi razonamiento, ver más abajo). Pregunta 2: Alternativamente, ¿qué me estoy perdiendo?
He aquí por qué creo que podría ser un error del compilador. Examina el siguiente código:
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
El método void Add(KeyValuePair<string, int> item)
parece no estar en Dictionary<string,int>
(ya que no se compila), pero está en IDictionary<string,int>
, y de alguna manera el compilador funciona correctamente Encuentra una implementación de ello. Pregunta 3: ¿Qué está pasando?
Tenga en cuenta que la documentación de Microsoft para el Dictionary<K,V>
no especifica estos tres métodos.
Por último, en mi implementación real, terminé usando
IDictionary<string,int> _backingDictionary = new Dictionary<string,int>();
en lugar de
Dictionary<string,int> _backingDictionary = new Dictionary<string,int>();
para que los tres métodos puedan funcionar fácilmente.
El Dictionary<TKey, TValue>
implementa estos métodos, simplemente lo hace explícitamente. Por lo tanto, debe acceder a través de la IDictionary<TKey, TValue>
.
Dictionary<string, string> map = ...;
KeyValuePair<string, string> pair = ...;
map.Add(pair); // Compilation Error
((IDictionary<string, string>)map).Add(pair); // Works
La implementación explícita funciona especificando con precisión qué método de interfaz implementa un método de instancia en el punto de definición. Por ejemplo
interface IFoo {
void Method();
}
class C1 : IFoo {
// Implicitly implements IFoo.Method
public void Method() { }
}
class C2 : IFoo {
// Explicitly implements IFoo.Method
void IFoo.Method() { }
}