Irgendwie kompiliert folgender Code nicht in VS2010, kompiliert aber in VS2012 ohne Änderungen. Die problematische Zeile in VS2010 ist
%Vor%%Vor%Fehler CS1928: 'string []' enthält keine Definition für 'Select' und die beste Erweiterungsmethode 'System.Linq.Enumerable.Select & lt; TSource, TResult & gt; (System.Collections.Generic.IEnumerable & lt; TSource & gt; , System.Func & lt; TSource, TResult & gt;) hat einige ungültige Argumente.
Aktualisierte Antwort
Ich habe überprüft, dass das Code-Snippet names.Select(foo.GetName)
in VS 2012 kompiliert und nicht auf VS2010 kompiliert.
Ich kenne den Grund nicht (um genau zu sein, die neue Funktion in C # 5.0 oder .NET 4.5 oder neue API), die es möglich gemacht hat.
Aber nach dem Fehler
%Vor% Es scheint, als ob Enumerable.Select
nicht in der Lage ist, den Parameter und den Rückgabetyp von foo.GetName
abzuleiten.
Wenn Sie den Typ angeben, wird der Code kompiliert.
Nachfolgend finden Sie die 3 Optionen
1. Casting nach Func<string,string>
2. Angeben von Typen als generische Parameter in Select
-Klausel
3. Call Function explizit im anonymen Delegaten.
%Vor%Aber wie Jon Skeet in Kommentaren darauf hinwies, fügt das oben Gesagte einen weiteren Funktionsaufruf hinzu, indem eine neue Methode erstellt wird.
ORIGINAL Antwort
Warum kompiliert dieser Code in VS2010 mit .NET 4.0 nicht?
Sie übergeben Parameter nicht an den Namen. Sie übergeben den Methodennamen anstelle von Func<T1,T2>
.
Das Folgende wird zusammengestellt
%Vor%Ich hatte das gleiche Problem in VSS 2010. Ich habe es behoben, indem ich das Zielframework auf 3.5 änderte. dann versuchen zu bauen. Wie erwartet, wird Ihr Build fehlschlagen, aber dieser Kick startet oder setzt einige interne Flags in VSS 2010 zurück. Wechseln Sie jetzt zurück zu .NET 4.0, und VSS beginnt ordnungsgemäß zu bauen.
Es sieht so aus, als wäre es ein Fehler im c # 4-Compiler, der im c # 5-Compiler behoben wurde.
%Vor%ist ein syntaktischer Zucker für
%Vor%, obwohl foo.GetName eine Erweiterungsmethode ist. Letzteres funktioniert in VS2010 der erste nicht.
In Abschnitt 6.6 der C # -Sprachspezifikation wird, wenn über die implizite Konvertierung für eine Methode gesprochen wird, der Prozess beschrieben, in dem die Konvertierung stattfindet, und dann heißt es:
Beachten Sie, dass dieser Prozess zur Erstellung eines Delegaten für eine Erweiterungsmethode, wenn der Algorithmus von §7.6.5.1 keine gefunden hat Instanz Methode aber gelingt die Verarbeitung von E (A) als Aufruf einer Erweiterungsmethode (§7.6.5.2). Ein so erstellter Delegat erfasst die Erweiterungsmethode sowie das erste Argument.
Darauf basierend würde ich voll und ganz erwarten, dass diese Linie sowohl in VS2010 als auch VS2012 funktioniert (da sich der Wortlaut in der Spezifikation nicht ändert), aber nicht. Ich vermute, das ist ein Fehler.
Hier sehen Sie, wie IL in VS 2012 kompiliert wird (Kommentare gehören mir):
%Vor% Wie Sie sehen, wird der Delegat aus der Objektinstanz (foo) und dem Methodenzeiger erstellt, und genau das sollte auch in VS2010 passieren. Und das, wenn Sie die Delegat-Erstellung new Func<string, string>(foo.GetName)
explizit angeben.
Tags und Links .net c# visual-studio-2010 linq visual-studio-2012