2

有谁知道用 C# 中的无操作替换某些函数调用的好方法(通过反射或特殊属性)?

基本上,我想做的是这样的

#ifdef DEBUG

StopWatch.start();

#endif

DoSomething();

#ifdef DEBUG

StopWatch.stop();
Log.TimingInfo(StopWatch);

#endif

无需在我的代码中随处可见大量 ifdef。我可以用空对象模式替换它(我的 StopWatch 类)并有条件地为其分配空对象,但这与代码中的严格无操作相比仍然不理想。代码路径长度在这里非常重要,当我们不尝试收集时序结果时,我宁愿牺牲一些可读性来完全没有操作。

有谁知道是否有办法在 C# 中标记我的 StopWatch 类或方法,以便在编译器评估时根本不发出代码?

4

3 回答 3

11

[Conditional("DEBUG")]您可以使用以下属性注释您的方法:

class StopWatch
{
    [Conditional("DEBUG")]
    public void Start() { }

    [Conditional("DEBUG")]
    public void Stop() { }
}

这与对/#ifdef DEBUG的调用具有相同的效果。一个警告:条件方法必须返回 void。还有一些其他限制。有关详细信息,请参阅条件属性文档。StartStop

于 2010-11-12T20:42:04.500 回答
2

如果您使用的是 C# 3.0 或更高版本,则可以查看部分方法:

http://bartdesmet.net/blogs/bart/archive/2007/07/28/c-3-0-partial-methods-what-why-and-how.aspx

于 2010-11-12T20:37:45.477 回答
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 将其添加到您的程序中(确保您需要处理类创建时间惩罚)。您可以在我的博客文章中阅读更多关于此的内容。但它是俄语的。

于 2012-06-28T06:45:57.647 回答