Conditional是.net提供關於編譯的屬性描述,其作用是新增到方法或屬上,通過定義編譯符的方式告指示編譯器應忽略方法呼叫或屬性.在.NET中Debug 和 Trace 類中的方法都新增了這屬性的定義,主要用於方便在編譯的時候可以選擇性編譯相關調式和跟蹤程式碼。那我們平時在寫一個記錄跟蹤相關功能庫的時候,是否有考慮過這東西呢?
StopWatchExtend swe = new StopWatchExtend("test"); swe.Start("test"); Console.WriteLine("test"); swe.Start("test1"); Console.WriteLine("test1"); swe.End();
對於以上程式碼相信很多人不會陌生的,其實就是計算這個過程每塊程式碼所損耗的時間。但問題在於很多時候只希望在debug下才做這樣的操作,在release則是完全沒有必要的。那這個時候我們一般想到的是使用預編譯符。
#if DEBUG StopWatchExtend swe = new StopWatchExtend("test"); swe.Start("test"); #endif Console.WriteLine("test"); #if DEBUG swe.Start("test1"); #endif Console.WriteLine("test1"); #if DEBUG swe.End(); #endif
這樣的程式碼的確是讓人蛋痛的事情,當然也可以選擇在釋出編譯的時候註釋到相關程式碼。顯然這兩種做法都是比較讓人捉狂的……這個時候就可以通過Conditional來解決以上問題。只需要在StopWatchExtend方法新增相關Conditional即可。
[Conditional("DEBUG")] public void End() { if (mCurrentItem != null) { mStopWatch.Stop(); mCurrentItem.UseTime = mStopWatch.Elapsed.TotalMilliseconds; mItems.Add(mCurrentItem); mCurrentItem = null; } } [Conditional("DEBUG")] public void Start(string name) { if (mCurrentItem != null) { mStopWatch.Stop(); mCurrentItem.UseTime = mStopWatch.Elapsed.TotalMilliseconds; mItems.Add(mCurrentItem); mCurrentItem = null; } mCurrentItem = new WatchItem(name, 0); mStopWatch.Reset(); mStopWatch.Start(); } [Conditional("DEBUG")] public void Start(string format, params object[] datas) { Start(string.Format(format, datas)); }
通過新增以上屬性後,那編寫前面的計時程式碼在釋出的時候就會省上很多事情,只需要在編譯專案裡把DEBUG移走,那StopWatchExtend的End和Start方法都不會被編譯過去.
有DEBUG生成的程式碼
StopWatchExtend swe = new StopWatchExtend("test"); swe.Start("test"); Console.WriteLine("test"); swe.Start("test1"); Console.WriteLine("test1"); swe.End();
沒有DEBUG生成的程式碼
StopWatchExtend swe = new StopWatchExtend("test"); Console.WriteLine("test"); Console.WriteLine("test1");