在课堂上,我有一个跟踪方法,如下所示:
[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
括起来。
我真正想要的是在嵌套类和成员变量上使用该属性或类似的东西。那可能吗?
答案 0 :(得分:2)
重新开始;关于[Conditional]
的要点是,调用者的构建是否实际执行调用 - 始终包含声明/实现代码;所以假设你的代码是一个独立的库;你必须包含枚举,否则调用者(假设调用者是独立的)不能可能曾调用该方法。
听起来#if
更适合你的问题 - 或者你可以在构建中使用条件包含(csproj支持这一点,虽然它有可能引起混淆; #if
会更明显)。
请注意,要执行重载解析,必须首先识别类型,因此您无法真正将#if
与[Conditional]
混合,因为枚举位于签名中。