System.Diagnostics.ConditionalAttribute并有条件地编译支持类型和变量

时间:2009-11-03 22:17:29

标签: c#

在课堂上,我有一个跟踪方法,如下所示:

    [System.Diagnostics.ConditionalAttribute("Trace")]
    private void TraceOutput(TraceBits bits, string format, params object[] varParams)
    {
        if ((bits & _DesiredTrace) != 0)
        {
           ...emit trace here...
        }
    }

TraceBits是[Flags] enum。每次调用TraceOutput都会传入调用标记的位。像这样:

    TraceOutput(TraceBits.Fill,
                "Fill     lock     wi({0}) stat({1}) iba({2}) nf({3})",
                workitem.index,
                workitem.status,
                workitem.inputBytesAvailable,
                _nextToFill
                );

这些位是:创建,读取,写入,填充等._ DesiredTrace是一个(私有成员变量)位域,指示应该实际发出哪些跟踪语句。这样我可以有选择地为类中的各个函数部分打开trace语句。如果我只想跟踪构造和销毁,我在该成员位域中设置了Create位。

我可以在方法上使用ConditionalAttribute,但该属性不适用于成员变量或嵌套类型(如TraceBits)。

因此,无论是否定义Trace,支持跟踪的类型和变量都会编译到代码中。如果未定义Trace,则完全没有必要。

是否有一种干净的方式来有条件地编译支持类型和变量?

我知道我可以使用#if Trace ... #endif来包围声明和TraceOutput的所有调用,以及所有支持的东西,但这会使代码变得丑陋。我喜欢ConditionalAttribute的清晰外观,其中每次调用TraceOutput都不需要用#if Trace括起来。

我真正想要的是在嵌套类和成员变量上使用该属性或类似的东西。那可能吗?

1 个答案:

答案 0 :(得分:2)

重新开始;关于[Conditional]的要点是,调用者的构建是否实际执行调用 - 始终包含声明/实现代码;所以假设你的代码是一个独立的库;你必须包含枚举,否则调用者(假设调用者是独立的)不能可能调用该方法。

听起来#if更适合你的问题 - 或者你可以在构建中使用条件包含(csproj支持这一点,虽然它有可能引起混淆; #if会更明显)。

请注意,要执行重载解析,必须首先识别类型,因此您无法真正将#if[Conditional]混合,因为枚举位于签名中。