C#編譯器csc.exe
和C#語言本身不會爲conditional compilation公開任何預定義的常量。 VisualStudio
僅添加了可通過IDE配置的DEBUG
和TRACE
值。 IDE還允許您添加自己的任意符號,但由於這些符號基本上是固定的(不變的)值,因此該功能的使用受到限制。
更強大的自定義選項可以通過手動編輯您的.csproj
項目文件來設置。根據MSBuild(見here和here)提供的大量環境和配置信息,您可以在這裏將conditions設置爲selectively propagate以selectively propagate條件編譯爲C#,但原則上可能沒有完整列表,因爲不同組件會任意貢獻元數據特設)。
讓我們考慮一個工作示例。有條件編譯有用的一種情況是,如果您想編寫適合構建過程中發現的任何工具的代碼。通過這種方式,您可以利用最新的語言功能,同時仍能夠保留在具有較舊工具的機器上進行編譯的能力,而這正如預期的那樣會拒絕外來語法和/或關鍵字。對於C# 7.0在vs2017
特定的情況下,我們可以通過修改.csproj
如下:
.csproj的文件(節選):
您還可以識別每個上了年紀的C#編譯器,以及,一路上優雅地退化。這同樣適用於檢測所述.NET Framework
版本(經常要求在計算器上[1] [2] [3] [4])和任何其它環境條件的構建。這些作爲練習留給讀者,但如果你想從上面複製/粘貼突出顯示的行,這裏是文本版本。由於在截屏的更新,我加了單引號的條件表達式這裏(即使一切似乎沒有他們的工作)
<DefineConstants Condition="'$(VisualStudioVersion)'=='15'">CSHARP7</DefineConstants>
<!-- ... -->
<DefineConstants>DEBUG;TRACE;$(DefineConstants)</DefineConstants>
<!-- ... -->
<DefineConstants>TRACE;$(DefineConstants)</DefineConstants>
不管怎麼說,以這種方式,你現在就可以編寫使用#if… #elif… #else… #endif
有條件的C#代碼 。繼續這個例子,下面的代碼使用新的元組語法 - 只在C#7中可用 - 交換數組元素。順便提一句,元組版本不僅更簡潔和/或優雅,它也產生優異的IL代碼:
#if CSHARP7
(rg[i], rg[j]) = (rg[j], rg[i]); // swap elements: tuple syntax
#else
var t = rg[i]; // swap elements: clunky
rg[i] = rg[j];
rg[j] = t;
#endif
注意,Visual Studio
IDE 確實正確處理您的人工.csproj
自定義在每一個方面。鑑於.csproj
我之前展示的IDE代碼編輯器可以正確識別和評估爲目的,條件編譯IntelliSense
,refactoring
,「調出」的代碼不激活塊等
我也提到了MSBuild
有一個寶庫的信息可用,其中$(VisualStudioVersion)
只是一個例子。不幸的是,不容易找出哪些值是可用的,以及它們在構建時可能具有的值。一個訣竅就是臨時把C++
項目放到你的C#項目旁邊的Visual Studio
解決方案中(如果你還沒有的話)。如果您右鍵點擊項目屬性對於此.vcxproj
,然後查看(例如,)「附加包含目錄」的C/C++
頁面上,一個下拉菜單會出現在最右邊,當您單擊編輯:
你會得到一個對話框,以「宏」按鈕,就可以單擊以獲取所有可用變量的列表以及根據當前在IDE中選擇的平臺和配置的預期值。請不要忽略列表底部的well-known-item-metadata字段(前綴爲%
)。
你可以得到很多東西是如何在這裏從這張截圖的滾動條拇指大小的想法。 (它們按字母順序排列,我只是滾動到「P」部分的這部分,因爲它的個人信息很少)。然而,需要注意的是,在構建過程中,(可用)變量及其值隨着時間的推移而變化,因此您可能會發現此列表中的項目在處理時不可用於您的.csproj
。
Awsome!這個答案需要更多的投票!特別是對於C++提示:-) – Matt 2017-05-12 13:16:16