有没有人知道用C#中的no-op替换某些函数调用的好方法(通过反射或特殊属性)?
基本上,我要做的就是这样的事情
#ifdef DEBUG
StopWatch.start();
#endif
DoSomething();
#ifdef DEBUG
StopWatch.stop();
Log.TimingInfo(StopWatch);
#endif
我的代码中没有遍布很多ifdef。我可以用空对象模式替换它(我的StopWatch类)并有条件地为它分配空对象,但与代码中的严格无操作相比,这仍然不理想。代码路径长度在这里非常重要,当我们不尝试收集时序结果时,我宁愿牺牲一些读取能力来完全没有操作。
有没有人知道是否有办法在C#中标记我的StopWatch类或方法,以便在编译器评估时不会发出代码?
答案 0 :(得分:11)
您可以使用[Conditional("DEBUG")]
属性注释您的方法,例如:
class StopWatch
{
[Conditional("DEBUG")]
public void Start() { }
[Conditional("DEBUG")]
public void Stop() { }
}
这与调用#ifdef DEBUG
/ Start
的{{1}}效果相同。一个警告:条件方法必须返回void。还有一些其他限制。有关详细信息,请参阅ConditonalAttribute文档。
答案 1 :(得分:2)
如果您使用的是C#3.0或更高版本,则可以查看部分方法:
http://bartdesmet.net/blogs/bart/archive/2007/07/28/c-3-0-partial-methods-what-why-and-how.aspx
答案 2 :(得分:0)
您可以使用此类,它还包括记录到visual studio的输出窗口:
public static class TimerCalls
{
private static Dictionary _Stopwatches = new Dictionary();
[ConditionalAttribute("TIMERS")]
public static void StartStopwatch(string key)
{
if (_Stopwatches.ContainsKey(key)) //Stopwatch already running
return;
_Stopwatches.Add(key, Stopwatch.StartNew());
}
[ConditionalAttribute("TIMERS")]
public static void StopStopwatch(string key)
{
if (!_Stopwatches.ContainsKey(key))//No such stopwatch currently
return;
var watch = _Stopwatches[key];
watch.Stop();
_Stopwatches.Remove(key);
Debug.WriteLine(String.Format("Timer: {0}, {1}ms ---- {2}", key,
watch.Elapsed.TotalMilliseconds, DateTime.Now));
}
}
以及“如何使用”:
TimerCalls.StartStopwatch("Operations");
// many operations..
TimerCalls.StopStopwatch("Operations");// Timer: Operations, 508ms ---- 27.06.2012 11:41:06
它使用条件符号TIMERS,可以通过visual studio项目属性或#define添加到您的程序中(确保您需要处理类创建时间惩罚)。 您可以在blog post中了解更多内容。但它是俄语。