Reputation: 192637
In a class, I've got a trace method that looks like this:
[System.Diagnostics.ConditionalAttribute("Trace")]
private void TraceOutput(TraceBits bits, string format, params object[] varParams)
{
if ((bits & _DesiredTrace) != 0)
{
...emit trace here...
}
}
TraceBits is a [Flags] enum
. Each call to TraceOutput passes in the bit that the call is tagged with. Like this:
TraceOutput(TraceBits.Fill,
"Fill lock wi({0}) stat({1}) iba({2}) nf({3})",
workitem.index,
workitem.status,
workitem.inputBytesAvailable,
_nextToFill
);
The bits are: Create, Read, Write, Fill, etc. _DesiredTrace is a (private member variable) bitfield that indicates which trace statements should be actually emitted. This way I can selectively turn on trace statements for various portions of function within the class. If I want to trace only construction and destruction, I set the Create bit in that member bitfield.
I can use the ConditionalAttribute
on the method, but that attribute doesn't work on member variables or nested types (like TraceBits).
As a result, the types and variables that support tracing, are compiled into the code, whether or not Trace
is defined. If Trace is undefined then these are completely unnecessary.
Is there a clean way to conditionally compile the supporting types and variables in?
I know I can use #if Trace ... #endif
to surround the declaration and all invocations of TraceOutput, as well all the supporting stuff, but that uglifies the code. I like the cleaner look of the ConditionalAttribute
, where each call to TraceOutput does not need to be bracketed with #if Trace
.
What I really want is some way to use that attribute, or something like it, on nested classes and member variables. Is that possible?
Upvotes: 2
Views: 319
Reputation: 1064114
Re the enum; the point about [Conditional]
is that it is up to the caller's build whether to actually perform the invoke - the declaring/implementing code is always included; so assume that your code is a standalone library; you must include the enum, otherwise the caller (assume the caller is separate) cannot possibly ever call the method.
It sounds like #if
is a better fit for your problem - or you could use conditional inclusion in the build (csproj supports this, although it risks causing confusion; #if
would be more obvious).
Note that to perform overload resolution it must first identify the types, so you can't really mix #if
with [Conditional]
since the enum is in the signature.
Upvotes: 2