我昨天在Visual Studio 2015中打开了我们的解决方案,发现一些单元测试(在Visual Studio 2013中运行良好)开始失败。进一步深入研究,我发现这是因为在程序集上调用
在Visual Studio 2013和2015中,我都使用.NET Framework 4.5.2创建了一个新的控制台应用程序。我在这两个项目中放置了以下代码。
当我在Visual Studio 2013中运行时,我得到了如下输出(如预期)。
“VS2013Example.Program”
当我在Visual Studio 2015中运行时,我得到了如下输出(不是预期的)。
“VS2015Example.Program” “VS2015Example.Program+<>c”
那么这个“VS2015Example.Program+<>c”类型是什么?原来它是
我使用Beyond Compare比较了两个.csproj文件,但唯一的区别是VS版本号、项目GUID、默认命名空间和程序集的名称,以及VS2015引用了VS2013没有的System.Net.Http。
有其他人看到过这个问题吗?
有人能解释一下为什么一个局部变量会被公开为程序集级别的类型吗?
GetTypes()
返回不同的结果。我已经能够创建一个非常简单的测试用例来说明这个问题。在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+<>c”
那么这个“VS2015Example.Program+<>c”类型是什么?原来它是
.Where()
方法内部的lambda表达式。是的,没错,某种方式将该局部lambda表达式公开为类型。如果我在VS2015中注释掉.Where()
,则不再会出现第二行。我使用Beyond Compare比较了两个.csproj文件,但唯一的区别是VS版本号、项目GUID、默认命名空间和程序集的名称,以及VS2015引用了VS2013没有的System.Net.Http。
有其他人看到过这个问题吗?
有人能解释一下为什么一个局部变量会被公开为程序集级别的类型吗?
GetTypes()
应该有一个重载,让开发人员明确地声明他们是否想要包括编译器生成的类型。 - Craig W.Assembly.GetTypes
时,您确实希望看到程序集中的所有类,即使它们是由编译器生成的。 - Yuval Itzchakov