C# 中用于获取无操作结果的条件编译技术

发布于 2024-10-02 22:50:11 字数 425 浏览 4 评论 0原文

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

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

#ifdef DEBUG

StopWatch.start();

#endif

DoSomething();

#ifdef DEBUG

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

#endif

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

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

Does anyone know a good way (either through reflection or special attributes) to replace certain functions calls with no-ops in C#?

Basically, what I'm trying to do is something like this

#ifdef DEBUG

StopWatch.start();

#endif

DoSomething();

#ifdef DEBUG

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

#endif

without sprinkling a lot of ifdefs everywhere in my code. I could replace this (my StopWatch class) with a null object pattern and assign it the null object conditionally, but this is still not ideal compared to strictly no-op in the code. The code path length is very important here, and i'd rather sacrifice some read-ability for having absolutely no op when we're not trying to collect timing results.

Does anyone know if there is a way to tag my StopWatch class or methods in C# to simply not emit code when evaluated by the compiler?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

下壹個目標 2024-10-09 22:50:11

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

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

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

这与调用 Start#ifdef DEBUG 具有相同的效果代码>/<代码>停止。需要注意的是:条件方法必须返回 void。还有一些其他限制。有关详细信息,请参阅 ConditonalAttribute 文档。

You can annotate your methods with the [Conditional("DEBUG")] attribute like:

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

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

This has the same effect as #ifdef DEBUG around calls to Start/Stop. One caveat: conditional methods must return void. There are a few other restrictions as well. See the ConditonalAttribute documentation for details.

琴流音 2024-10-09 22:50:11

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

http://bartdesmet.net/blogs/bart/archive/2007/07/28/c-3-0-partial-methods-what-为什么和如何.aspx

If you're on C# 3.0 or later, you could look into partial methods:

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

忘年祭陌 2024-10-09 22:50:11

您可以使用这样的类,它还包括记录到 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 添加到您的程序(当然您需要处理类创建时间惩罚)。
您可以在我的博客文章中阅读更多相关内容。但它是俄语的。

You can use such class, it also includes logging to visual studio's output window:

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));
    }
}

And "how to use":

TimerCalls.StartStopwatch("Operations");
// many operations..
TimerCalls.StopStopwatch("Operations");// Timer: Operations, 508ms ---- 27.06.2012 11:41:06

It uses conditional symbol TIMERS that can be added to your program via visual studio project properties or with #define(sure you will need to deal with the class creation time penalties).
You can read more in my blog post about that. But its in russian.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文