2014-03-04 6 views
29

Lassen Sie uns die folgende Erweiterung Methode nehmen:verwirrt, warum diese C# Code kompiliert, während ähnlichen Code nicht

static class Extensions 
{ 
    public static bool In<T>(this T t, params T[] values) 
    { 
     return false; 
    } 
} 

Ich bin neugierig, warum diese Code kompiliert und ausgeführt:

var x = new Object(); 
IEnumerable<int> p = new List<int> { 1, 2, 3 }; 
var t2 = x.In(p); 

Innerhalb In, values ist ein Object[], als ob die List<int> im laufenden Betrieb in ein Array konvertiert wird. Für mich scheint es, dass params T[] nicht IEnumerable<int> entspricht, weshalb ich überrascht bin, dass dies sogar läuft.

nun dieser Code:

var x = 5; 
IEnumerable<int> p = new List<int> { 1, 2, 3 }; 
var t2 = x.In(p); 

Does nicht Lauf und gibt den Compiler-Fehler:

Error 2 Argument 2: cannot convert from 'System.Collections.Generic.IEnumerable' to 'int[]'

Dies ist, was ich von dem ersten erwarten würde tatsächlich. Kann mir jemand erklären, was hier vor sich geht? Vielen Dank!

+0

Fragen Sie, warum der erste kompiliert oder warum der zweite nicht? – SLaks

+0

@SLaks - Ich habe mich meistens gefragt, warum das * erste * * * kompiliert, aber deine Antwort hat es perfekt genagelt. –

+0

Dann sollten Sie Ihren Titel ändern. :) – SLaks

Antwort

41

Typ-Inferenz konvertiert Ihren ersten Aufruf von

In<object>(x, p); 

Die Parametern dieses generische Methode geschlossen object, params object[] sind.
Daher übergibt implizit konvertiert es in eine object, die das einzige Element im Array params wird.

Ihr zweiter Anruf wird gefolgert, (wegen der ersten Parameter) zu

In<int>(x, p); 

Hier kann der zweite Parameter entweder eine int[] (vorbei an ein Array direkt) oder eine Reihe von int s (via params) .
Da IEnumerable<int> keiner von denen ist, erhalten Sie einen Fehler.

+0

Doh! Ich habe die Tatsache völlig übersehen, dass "Werte" ein Array von 1 Element und nicht 3 waren, als ich dies debuggte, da der Mauszeiger die Werte automatisch vergrößert. Hätte ich das gesehen, hätte ich das sofort verstanden! –

+2

@MikeChristensen Nun, ich [habe erklärt, dass Sie Sie früher] (http://stackoverflow.com/questions/22179175/c-sharp-how-can-i-make-an-extension-accept-ienumerable-instead-of-) -array-for-para/22179217? noredirect = 1 # commentar33665841_22179218) ... Zugegeben, ich habe es im Code erklärt, nicht in Worten. – Servy

+0

@MikeChristensen Ich habe deine Frage nicht abgelehnt. Es ist nicht sehr reif, solche Annahmen zu treffen. Aus Gründen der Übersichtlichkeit ging ich davon aus, dass Sie in der Lage sein würden, die Implikationen zu erkennen, wenn man bedenkt, dass das IEnumerable in ein Array eingebettet ist, wie Sie gesagt haben (http://stackoverflow.com/questions/22180670)/confused-wie-warum-dieser-c-sharp-code-does-not-compile/22180752? noredirect = 1 # comment3367209_22180752). – Servy