Ich öffnete unsere Lösung in Visual Studio 2015 gestern und einige unserer Unit-Tests (die in Visual Studio 2013 einwandfrei funktionierte) starten fehlgeschlagen. Digger Tiefer ich entdeckte, dass es war, weil das Anrufen GetTypes()
auf einer Versammlung unterschiedliche Ergebnisse zurückgab. Ich konnte einen sehr einfachen Testfall erstellen, um es zu veranschaulichen.Verhalten von Assembly.GetTypes() in Visual Studio 2015 geändert
In Visual Studio 2013 und 2015 habe ich eine neue Konsolenanwendung mit .NET Framework 4.5.2 erstellt. Ich habe den folgenden Code in beide Projekte eingefügt.
class Program
{
static void Main(string[] args)
{
var types = typeof(Program).Assembly.GetTypes()
.Where(t => !t.IsAbstract && t.IsClass);
foreach (var type in types)
{
Console.WriteLine(type.FullName);
}
Console.ReadKey();
}
}
Wenn ich in Visual Studio 2013 ausführen, erhalte ich (wie erwartet) die folgende Ausgabe.
VS2013Example.Program
Als ich in Visual Studio 2015 betreibe ich die folgende Ausgabe erhalten (nicht wie erwartet).
VS2015Example.Program
VS2015Example.Program + <> c
Also, was ist, dass VS2015Example.Program+<>c
Typ? Stellt sich heraus, es ist das Lambda innerhalb der .Where()
Methode. Ja, das stimmt, irgendwie wird das lokale Lambda als ein Typ herausgestellt. Wenn ich die .Where()
in VS2015 auskommentiere, dann bekomme ich diese zweite Zeile nicht mehr.
Ich habe Beyond Compare verwendet, um die beiden .csproj-Dateien zu vergleichen, aber die einzigen Unterschiede sind die VS-Versionsnummer, die Projekt-GUID, die Namen des Standardnamespace und der Assembly, und die VS2015 hatte einen Verweis auf System.Net .Http, dass der VS2013 nicht.
Hat jemand anderes dies gesehen?
Hat jemand eine Erklärung, warum eine lokale Variable als ein Typ auf der Assembly-Ebene exponiert würde?
Danke für die Info. Scheint ein wenig beängstigend, weil es sich wie eine Veränderung anfühlt, die wahrscheinlich viel existierenden Code verursacht, der gut funktioniert hat, um plötzlich Bugs zu zeigen. Im Laufe der Jahre habe ich nicht mehr gezählt, wie oft ich Code geschrieben habe, der die Typen in einer Baugruppe aufzählt. Empfindungen wie 'GetTypes()' sollten vielleicht eine Überladung haben, die den Entwickler explizit angeben lässt, ob sie die vom Compiler generierten Typen enthalten wollen. –
@CraigW. Sollte es ziemlich einfach sein, eine Erweiterungsmethode dafür zu schreiben, aber ich stimme völlig zu, dass es eine potentielle Bruchänderung ist, denn selbst mit einer Erweiterungsmethode würde es nicht standardmäßig aufgerufen werden, vielleicht sollten Sie ein Problem mit dem Roslyn-Team auf GitHub einreichen? –
@Craig Dies ist keine brechende Änderung, das ist ein *** Implementierungsdetail ***. Wenn Sie eine Variable in Ihrem Delegaten erfasst hätten, würden Sie das gleiche Verhalten sehen. –