2017-11-30 277 views
8

kawałek kodu C#Problem z debugowaniem VS, kto może mi pomóc wyjaśnić to poniżej?

var isTrue = (new List<int>{1,2,3} is IEnumerable<object>); 

mam wynik false wykonanie kodu, ale kiedy skopiować ten kod do okna Watch, wynik jest true.

+1

Zakładam, że "IEnumable" to literówka? – casiosmu

+0

Możliwy duplikat [Różnica między kowariancją a przeciw-wariancją] (https://stackoverflow.com/questions/2184551/difference-between-covariance-contra-variance) –

+0

TL; DR: a 'Lista ' jest 'IEnumerable 'ale nie" IEnumerable ". "false" jest poprawnym wynikiem. –

Odpowiedz

0

To nie jest pełna odpowiedź (nie znam powodów, dla których ten błąd pojawia się), ale rzuca trochę światła na błędne zachowanie debuggera, które jest oczywiście błędne.

Przede wszystkim: typy wartości niedopuszczalności C# (i AFAIK, także CLR); wariancja jest dozwolone tylko wtedy, gdy istnieje tożsamość zachowaniu konwersję między zaangażowanymi typów, inaczej nie zadziała (nie ma tożsamości zachowaniu konwersję typów wartości):

object[] oo = new int[] {1, 2, 3}; //will fail 
IEnumerable<object> oo = new int[] {1, 2, 3}; //will fail 

natychmiastowe okno debugera jest oczywiście błędne, new List<int> { 1, 2, 3 } is IEnumerable<object> powinny powrócić false w miarę upływu czasu. Dlaczego powraca true? Ponieważ jest błąd, kropka.

Co czyni go jeszcze bardziej zdumiewające jest to, że new int[] { 1, 2, 3 } is IEnumerable<object> będzie correclty powrócić false gdy int[] jest niejawnie zamienny do IEnumerable<int> same jak List<int>.

Jedynym powodem, dla którego znajdę dla tego ostatniego poprawnego zachowania, jest to, że kompilator już teraz flaguje to wyrażenie jak zwykle false z ostrzeżeniem, a zatem sposób, w jaki kompilator analizuje scenariusz macierzy, jest różny od każdego innego IEnumerable.

+0

Tak, w oknie IDE pojawia się podejrzane ostrzeżenie o typie. W przypadku słów kluczowych kluczowym elementem jest erratic –