![](/img/trans.png)
[英]msbuild works on command line but VS2010 says a project is “not selected”
[英]Generated code differs when compiling solution in VS2010 or via MsBuild command line
我有以下C#代碼:
foreach (var x in m_collection)
{
m_actionCollection.Add(() =>
{
x.DoSomething();
});
}
如果我在VS2010中編譯解決方案,則會生成以下代碼(使用IlSpy進行反編譯):
foreach (var x in m_collection)
{
m_actionCollection.Add(() =>
{
x.DoSomething();
});
}
如果我通過MsBuild命令行編譯解決方案,則會生成以下代碼:
using (List<X>.Enumerator enumerator = this.m_collection.GetEnumerator())
{
while (enumerator.MoveNext())
{
X x = enumerator.Current;
m_actionCollection.Add(() =>
{
x.DoSomething();
});
}
}
項目文件包含
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
並且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中,它將在m_collection
每個項目上調用一次DoSomething
。
沒有幫助,不清楚ILSpy的語言版本有效反編譯為:(
必須完成/檢查才能通過MsBuild命令行和VS 2010建立完全相同的環境?
我強烈建議最簡單的方法是轉而使用VS2012或VS2013。
您可以通過查看msbuild日志來查看,並查看正在使用哪個版本的csc.exe
進行CoreCompile
步驟。 一旦知道正在使用哪個編譯器二進制文件 ,就可以根據需要從命令行運行編譯器以修改。
當我使用/toolsversion:4.0
運行msbuild
,它使用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() {} }
如果編譯時會發出警告 CS1998(“此async方法缺少等待運算符......”)那么它正在使用C#5編譯器。 較舊的編譯器會給出錯誤(可能是“Invalid token'void'...”)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.