Ho appena avuto un errore di test unitario per uno strano motivo che coinvolge IDictionary<object, object>
.In che modo questa risoluzione di sovraccarico ha senso?
IDictionary<K,V>
ha due metodi Remove
. Uno prende uno K
, l'altro prende uno KeyValuePair<K,V>
. Considerate queste due dizionari:
IDictionary<string, object> d1 = new Dictionary<string, object>();
IDictionary<object, object> d2 = new Dictionary<object, object>();
d1.Add("1", 2);
d2.Add("1", 2);
Console.WriteLine(d1.Remove(new KeyValuePair<string, object>("1", 2)));
Console.WriteLine(d2.Remove(new KeyValuePair<object, object>("1", 2)));
L'uscita è True
, quindi False
. Dal KeyValuePair<object,object>
è il tipo esatto previsto da d2.Remove(KeyValuePair<object,object>)
, perché il compilatore chiama invece il d2.Remove(object)
?
(post-mortem nota:
Nello scenario che ha spinto la mia domanda, non stavo usando IDictionary<object,object>
direttamente, ma piuttosto attraverso un parametro generico:
public class DictionaryTests<DictT> where DictT :
IDictionary<object,object>, new()
dal momento che il problema è che IDictionary
ha preso la priorità su ICollection
Ho deciso di "pareggiare" includendo ICollection
nell'elenco dei vincoli:
public class DictionaryTests<DictT> where DictT :
ICollection<KeyValuePair<object, object>>, IDictionary<object,object>, new()
ma questo non ha cambiato la mente del compilatore ... Mi chiedo perché no)
IIRC, questo è dovuto a una corrispondenza trovata nel 'tipo di dichiarazione' e non procede al tipo di base. Ho già fatto una domanda simile prima. Alla ricerca di un link Modifica: qui vai: http://stackoverflow.com/q/12242346/15541 (la tua domanda è un duplicato) – leppie
Doh! Beh, non è duplicato al 100% dato che la mia domanda riguarda un'interfaccia generica, giusto? '*' attende l'inevitabile chiusura * – Qwertie
Penso che lo stesso valga per qualsiasi tipo. – leppie