我昨天在Visual Studio 2015中打开了我们的解决方案,我们的一些单元测试(在Visual Studio 2013中运行正常)开始失败。深挖掘机我发现这是因为在程序集上调用GetTypes()
返回不同的结果。我已经能够创建一个非常简单的测试案例来说明它。Assembly.GetTypes()在Visual Studio 2015中的行为已更改
在Visual Studio 2013和2015中,我使用.NET Framework 4.5.2创建了一个新的控制台应用程序。我把这两个项目中的代码。
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();
}
}
当我在Visual Studio 2013中运行时,我得到以下输出(如预期的那样)。
VS2013Example.Program
当我运行在Visual Studio 2015年我得到下面的输出(未如预期)。
VS2015Example.Program
VS2015Example.Program + <>ç
那么,什么是VS2015Example.Program+<>c
类型?原来,这是.Where()
方法中的lambda。是的,这是正确的,不知何故,本地lambda被暴露为类型。如果我在VS2015中注释掉.Where()
,那么我不会再获得第二条线。
我已经使用Beyond Compare来比较两个.csproj文件,但唯一的区别是VS版本号,项目GUID,默认命名空间和程序集的名称,以及VS2015有一个对System.Net的引用.Http VS2013没有。
有没有其他人看到过这个?
有没有人有解释为什么一个局部变量会在汇编级别作为类型暴露?
感谢您的信息。看起来有点可怕,因为它感觉像一个变化,可能会导致很多现有的代码工作得很好,突然出现错误。多年来,我已经忘记了我编写代码的次数,这些代码列举了程序集中的类型。感觉像'GetTypes()'应该可能有一个重载,让开发人员明确地声明他们是否希望包含编译器生成的类型。 –
@CraigW。应该很容易编写一个扩展方法,但我完全同意这是一个潜在的重大变化,因为即使使用扩展方法,它不会默认调用,也许你应该在github上提交Roslyn团队的问题? –
@克雷格这不是一个突破性的变化,那是一个***实现细节***。如果你在委托中捕获了一个变量,你会看到相同的行为。 –