Otworzyłem nasze rozwiązanie w Visual Studio 2015 wczoraj i kilka naszych testów jednostkowych (które działały dobrze w Visual Studio 2013) zaczynało się nie udać. Odkrywam głębiej Odkryłem, że to dlatego, że wywołanie GetTypes()
na zespole zwróciło inne wyniki. Byłem w stanie stworzyć bardzo prosty przypadek testowy, aby go zilustrować.Zachowanie Assembly.GetTypes() zmienione w Visual Studio 2015
W obu Visual Studio 2013 i 2015 utworzyłem nową aplikację konsolową z .NET Framework 4.5.2. W obu projektach umieszczam poniższy kod.
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();
}
}
Po uruchomieniu programu Visual Studio 2013 otrzymuję następujące dane wyjściowe (zgodnie z oczekiwaniami).
VS2013Example.Program
Kiedy biegnę w Visual Studio 2015 pojawia się następujący komunikat (nie jak oczekiwano).
VS2015Example.Program
VS2015Example.Program + <> c
Więc co to jest VS2015Example.Program+<>c
typ? Okazuje się, że jest to lambda w metodzie .Where()
. Tak, to prawda, w jakiś sposób, że lokalna lambda jest eksponowana jako typ. Jeśli skomentuję numer .Where()
w VS2015, to nie będę już otrzymywać drugiej linii.
Użyłem Beyond Compare, aby porównać dwa pliki .csproj, ale jedyne różnice to numer wersji VS, GUID projektu, nazwy domyślnej przestrzeni nazw i zespołu, a VS2015 ma odniesienie do System.Net .Http, że VS2013 nie.
Czy ktoś jeszcze to widział?
Czy ktoś ma wyjaśnienie, dlaczego zmienna lokalna zostałaby przedstawiona jako typ na poziomie zespołu?
Dzięki za info. Wydaje się trochę przerażające, ponieważ wydaje się, że zmiana może spowodować wiele istniejącego kodu, który działa dobrze, aby nagle pokazać błędy. Przez lata straciłem rachubę ile razy napisałem kod, który wylicza na typy w zespole. Wygląda na to, że 'GetTypes()' powinien mieć przeciążenie, które pozwala deweloperowi jawnie określić, czy chce on zawierać typy generowane przez kompilator. –
@CraigW. Powinieneś być całkiem łatwy do napisania metody rozszerzenia, ale całkowicie zgadzam się, że jest to potencjalnie przełomowa zmiana, ponieważ nawet przy metodzie rozszerzenia nie byłaby ona domyślnie wywoływana, może powinieneś zgłosić problem z zespołem Roslyn na github? –
@Craig To nie jest przełomowa zmiana, to jest *** szczegóły dotyczące implementacji ***. Jeśli przechwyciłeś zmienną wewnątrz swojego delegata, zobaczysz to samo zachowanie. –