2009-11-03 9 views
1

在一個類中,我有一個跟蹤方法,看起來像這樣:System.Diagnostics.ConditionalAttribute和有條件編譯配套類型和變量

[System.Diagnostics.ConditionalAttribute("Trace")] 
    private void TraceOutput(TraceBits bits, string format, params object[] varParams) 
    { 
     if ((bits & _DesiredTrace) != 0) 
     { 
      ...emit trace here... 
     } 
    } 

TraceBits是[Flags] enum。每個對TraceOutput的調用都會傳入該呼叫標記的位。就像這樣:

TraceOutput(TraceBits.Fill, 
       "Fill  lock  wi({0}) stat({1}) iba({2}) nf({3})", 
       workitem.index, 
       workitem.status, 
       workitem.inputBytesAvailable, 
       _nextToFill 
       ); 

該位是:創建,讀取,寫入,填充等_DesiredTrace是(私有成員變量)位域指示跟蹤語句應該實際發射。通過這種方式,我可以有選擇地爲類中的各個函數部分打開跟蹤語句。如果我只想跟蹤構造和破壞,則在該成員位域中設置創建位。

我可以在該方法上使用ConditionalAttribute,但該屬性不適用於成員變量或嵌套類型(如TraceBits)。

因此,支持跟蹤的類型和變量會被編譯到代碼中,無論是否定義了Trace。如果Trace未定義,那麼這些都是不必要的。

有沒有一種乾淨的方式來有條件地編譯支持類型和變量?

我知道我可以使用#if Trace ... #endif來包圍聲明和TraceOutput的所有調用,以及所有支持的東西,但是代碼很醜。我喜歡ConditionalAttribute的清潔外觀,每個對TraceOutput的調用都不需要用#if Trace括起來。

我真正想要的是在嵌套類和成員變量上使用該屬性或類似的東西。那可能嗎?

回答

2

重新枚舉;關於[Conditional]的一點是,它是由調用者的構建是否實際執行調用 - 聲明/執行代碼總是包括;所以假設你的代碼是一個獨立的庫;你必須包括枚舉,否則調用者(假設調用者是分開的)不能可能有過調用方法。

聽起來好像#if更適合您的問題 - 或者您可以在構建中使用條件包含(csproj支持這一點,儘管它可能導致混淆; #if會更明顯)。

請注意,要執行重載分辨率,它必須首先確定類型,因此您無法真正混合#if[Conditional],因爲枚舉位於簽名中。