Har*_*y13 5 c# msbuild visual-studio-2010
我有以下C#代码:
foreach (var x in m_collection)
{
m_actionCollection.Add(() =>
{
x.DoSomething();
});
}
Run Code Online (Sandbox Code Playgroud)
如果我在VS2010中编译解决方案,则会生成以下代码(使用IlSpy进行反编译):
foreach (var x in m_collection)
{
m_actionCollection.Add(() =>
{
x.DoSomething();
});
}
Run Code Online (Sandbox Code Playgroud)
如果我通过MsBuild命令行编译解决方案,则会生成以下代码:
using (List<X>.Enumerator enumerator = this.m_collection.GetEnumerator())
{
while (enumerator.MoveNext())
{
X x = enumerator.Current;
m_actionCollection.Add(() =>
{
x.DoSomething();
});
}
}
Run Code Online (Sandbox Code Playgroud)
项目文件包含
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
Run Code Online (Sandbox Code Playgroud)
并且MsBuild命令行如下所示: C:\Windows\Microsoft.NET\Framework\v4.0.30319\MsBuild.exe Solution.sln /property:Configuration=Debug /property:Platform=x86 /maxcpucount /nologo /toolsversion:4.0
所以我假设编译器是相同的,但它不是......
必须完成/检查才能通过MsBuild命令行和VS 2010建立完全相同的环境?
我怀疑你看到C#5编译器(通过msbuild调用)和C#4编译器(VS2010)之间的区别.我对msbuild使用C#5编译器感到有些惊讶,但似乎......
如何foreach
捕获迭代变量的规则在C#4和C#5之间发生了变化.在C#5中,循环的每次迭代都foreach
有效地捕获了一个不同的变量.在C#4中,所有迭代都捕获相同的变量.
这意味着您的原始代码在C#4中被有效地破解,但在C#5中没有问题.在C#4中,如果您之后执行所有操作m_actionCollection
,它会很好,它会调用DoSomething()
最后一项m_collection
很多次(m_collection.Count
次).在C#5中,它会DoSomething
在每个项目上调用一次m_collection
.
没有帮助,不清楚ILSpy的语言版本有效反编译为:(
必须完成/检查才能通过MsBuild命令行和VS 2010建立完全相同的环境?
我强烈建议最简单的方法是转而使用VS2012或VS2013.
您可以通过查看msbuild日志来查看,并查看该步骤csc.exe
使用的版本CoreCompile
.一旦知道正在使用哪个编译器二进制文件,就可以根据需要从命令行运行编译器以进行修补.
当我msbuild
使用/toolsversion:4.0
它时c:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe
,它本身会报告:
Microsoft(R)Visual C#编译器版本4.0.30319.33440(适用于Microsoft(R).NET Framework 4.5)
这似乎是一个C#5编译器,尽管名称.我怀疑这是因为.NET 4.5是就地升级.
检查您真正使用的编译器的最简单方法是尝试包含async
方法.例如,这是一个完整的类:
class Test { static async void Foo() {} }
Run Code Online (Sandbox Code Playgroud)
如果编译时会发出警告 CS1998("此async方法缺少等待运算符......")那么它正在使用C#5编译器.较旧的编译器会给出错误(可能是"Invalid token'void'...")
归档时间: |
|
查看次数: |
305 次 |
最近记录: |