2010-09-24 17 views
11

在C#中使用條件編譯代碼的替代方案是什麼?C中條件編譯的替代方案#

我有一個有很多基於#ifdef的代碼的類。有時我的代碼是不可讀的。

尋找重構技術,爲更好的可讀性和代碼維護與許多#if DEFS使用

+0

爲什麼你首先需要它?它是關於調試信息的嗎? – Aliostad 2010-09-24 12:04:43

回答

23

一件事是使用ConditionalAttribute

[Conditional("DEBUG")] 
public void Foo() 
{ 
    // Stuff 
} 

// This call will only be compiled into the code if the DEBUG symbol is defined 
Foo(); 

它仍然是條件編譯,但基於屬性,而比#ifdef,這使它通常更簡單。

另一種方法是簡單地在執行時使用布爾值,而不是在編譯時全部使用布爾值。如果您可以向我們提供您想要實現的更多細節以及如何使用條件編譯,那將會很有用。

+0

在以字符串作爲參數的調試打印的情況下,儘管沒有評估任何參數,但仍然可以將這些字符串插入程序的可執行文件中。你知道從C#中獲得與C++的「#define DebugPrint((void)0)」相同的結果嗎? – 2015-12-22 22:37:01

+0

@布萊克:你確認這是真的嗎?雖然我可能是錯的,但我不會期待它。 – 2015-12-22 22:43:43

1

使用ConditionalAttribute將是一個開始。否則,通常可以通過反轉控制和/或合理使用工廠來處理人們通常對條件編譯所做的很多事情。

1

多態性。

以與在相同條件下有很多條件分支的意大利麪代碼相同的方式進行處理。

將基礎類或接口的差異摘錄出來。

根據構建構建具體類(一個#if)。將具體對象傳遞給您的應用程序,然後您的應用程序調用界面上定義的方法。

6

另一種方法是使用ConditionalAttribute。條件屬性以類似的方式工作。

#define TRACE_ON 
using System; 
using System.Diagnostics; 

public class Trace 
{ 
    [Conditional("TRACE_ON")] 
    public static void Msg(string msg) 
    { 
     Console.WriteLine(msg); 
    } 
} 

public class ProgramClass 
{ 
    static void Main() 
    { 
     Trace.Msg("Now in Main..."); 
     Console.WriteLine("Done."); 
    } 
} 
6

如果它是一個代碼可讀性的問題,你可以考慮使用的.Net的部分類資格,並把單獨的文件中有條件的代碼,所以也許你可以有這樣的事情......

FOO的.cs:

public partial class Foo 
{ 
    // Shared Behavior 
} 

foo.Debug.cs:

#if DEBUG 
public partial class Foo 
{ 
    // debug Behavior 
} 
#endif 

foo.bar.cs:

#define BAR 
#if BAR 
public partial class Foo 
{ 
    // special "BAR" Behavior 
} 
#endif 

我不知道你是否能定義代碼文件之外的條件語句了,所以做這樣的事情可能會降低的靈活性有條件的定義(例如您可能無法在主文件中針對BAR創建條件分支,並且必須維護多個定義的BAR可能會變得難看),並且需要特定的dilligence才能訪問文件以有效地啓用/禁用該位的代碼。

因此,使用這種方法可能會導致比解決更復雜的問題,但根據您的代碼,它可能會有幫助嗎?

0

如果您使用條件編譯的原因可以很容易地重構,您可以考慮使用Managed Extensibility Framework根據運行時的條件動態加載代碼。

0

對Jon的答案進行了擴展,但在使用ConditionalAttribute時存在一些限制,這有一個顯着的優勢。當條件爲false時,對條件方法的調用將被省略。例如,您可以將100個調用添加到日誌記錄系統中,比如調試,這可以有條件地從生產代碼中排除。當它們被排除在外時,沒有與調用不需要調用的方法相關的開銷。使用#ifdef,您必須將每次調用包裝到日誌記錄系統,纔能有條件地排除它們。

注意如果條件方法的調用者被重新編譯,這隻適用於程序集。