2016-10-11 62 views
4

是否有可能在編譯時檢測C#的當前版本是否爲6或以上,並帶有預處理器指令?在編譯時檢測C#版本

我想要做這樣的事情:

var myVar = ...; 
string name; 

#if VERSION_6_OR_MORE 
    name = nameof(myVar); 
#else 
    name = "myVar"; 
#endif 

我使用Visual Studio 2015和C#6,這樣我就可以使用nameof()。然而,其他人想要編譯此代碼可能會使用舊版本,其中nameof()不存在。

我想使用預處理器指令,因此我可以將nameof()保留在C#6中,但其他不使用該版本的人也可以編譯它。

+3

你爲什麼想做這樣的事情嗎? – Fka

+0

看看這個答案:[如何在C#中獲取當前產品版本?](http://stackoverflow.com/a/7382420/6741868)。 –

+0

@KeyurPATEL OP需要.NET Framework版本 - 而不是構件的構建版本。 – Filburt

回答

5

nameof()經營者是指,以降低維護:使用它,你不必隱藏在字符串標識符,所以當你重命名一個變量,參數或成員,在您使用它(例如一個ArgumentNullException(nameof(paramName)))地點將是當您重構paramName名稱時更新。

現在用你的方法,你有效是加倍您的維護表面,而不是降低它(因爲你現在有兩個字符串變種nameof()版本,兩者保持不必),否定一起使用nameof()

因此,如果您想支持較早的C#版本,請遵循適用於這些版本的功能:改爲在字符串中使用標識符。

+2

或告訴你的同事更新VS :) – slawekwin

+0

你一定是對的,我更喜歡使用'nameof',它允許重命名變量而不必根據這個變量檢查​​所有的字符串。但如果我的同事無法更新它將很難保持。我會放棄'nameof',然後:-( –

-1

不知道關於這樣的常量,但是......

喜歡的東西typeof(int).Assembly.ImageRuntimeVersion可以在運行時助陣。

此外: 您可以創建常量:

<DefineConstants Condition=" '$(LanguageVersion)' == 'v6.0' ">USING_CS6</DefineConstants> 
<DefineConstants Condition=" '$(LanguageVersion)' != 'v6.0' ">NOT_USING_CS6</DefineConstants> 

我沒有測試這個雖然。

+0

我不這麼認爲,op想在運行時找到它。 – Fka

+1

@Fka,這是編譯時間。 –

+0

在您編輯之後,它是:) – Fka

1

C#編譯器不允許您使用數值定義符號。任何符號是定義的undefined,這意味着它只是一個布爾值。

#define//define#if都不支持布爾以外的任何語法。

所有C#版本至今都與以前的版本向後兼容(除了像在foreach循環迭代變量語義一些細微差別),因此,如果你想寫兼容舊版本的代碼,只是不使用新功能。

您可以在構建腳本中檢測到可用的編譯器版本之後在外部定義一個符號,但這不值得冒險IMO,因爲較低版本的C#代碼比分散在代碼中的重複塊更易讀易維護。

2

我不知道有預先存在的指令。但是,這裏是你可以做什麼:

  1. 定義兩個創建配置:(在配置 經理)說CSharp6和CSharp5。
  2. 從配置管理器中選擇C6,然後轉到項目屬性。並定義一個符號說CSHARP6。
  3. 更改配置,並再次
  4. 打開項目屬性去CSharp5並定義一個新的符號:CSHARP5

那麼你的指令條件會是什麼樣子:

#if CSHARP6 
    name = nameof(myVar); 
#else 
    name = "myVar"; 
#endif 

委派配置的選擇或者作爲編譯項目的指導手冊的一部分。

2

可以明確的語言版本,並在您的項目文件中定義的條件不變:

<LangVersion>6</LangVersion> 
<DefineConstants>DEBUG;TRACE</DefineConstants> 
<DefineConstants Condition="'$(LangVersion)' == '6'">DEBUG;TRACE;LANG_VERSION_6</DefineConstants>