Po prostu test jednostkowy zakończył się niepowodzeniem z dziwnego powodu z udziałem IDictionary<object, object>
.Jak ta rozdzielczość przeciążania ma jakiś sens?
IDictionary<K,V>
ma dwie metody: Remove
. Jedna zajmuje K
, druga zajmuje KeyValuePair<K,V>
. Rozważmy te dwa słowniki:
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)));
Wyjście jest True
, następnie False
. Ponieważ KeyValuePair<object,object>
jest dokładnym typem oczekiwanym przez d2.Remove(KeyValuePair<object,object>)
, dlaczego zamiast tego kompilator wywołuje d2.Remove(object)
?
(Pośmiertne uwaga:
W scenariuszu, które spowodowały moje pytanie, ja nie używałem IDictionary<object,object>
bezpośrednio, lecz za pośrednictwem parametru rodzajowego:
public class DictionaryTests<DictT> where DictT :
IDictionary<object,object>, new()
ponieważ problem jest to, że IDictionary
miało pierwszeństwo przed ICollection
Postanowiłem "wyrównać rzeczy", włączając ICollection
na liście ograniczeń:
public class DictionaryTests<DictT> where DictT :
ICollection<KeyValuePair<object, object>>, IDictionary<object,object>, new()
ale to nie zmieni zdanie kompilator za ... Zastanawiam się dlaczego nie)
IIRC, jest to spowodowane do znalezienia w "rodzaju deklaracji" i nie przechodzi do typu bazowego. Zadałem już podobne pytanie. Szukam łącza. Edycja: Tutaj możesz: http://stackoverflow.com/q/12242346/15541 (twoje pytanie jest duplikatem) – leppie
Doh! Cóż, to nie jest w 100% duplikat, ponieważ moje pytanie dotyczy ogólnego interfejsu? '*' czeka na nieuchronne zamknięcie * – Qwertie
Myślę, że to samo dotyczy każdego typu. – leppie