.net好好地利用Conditional属性
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");
访问Beetlex的Github