Cheeso
Cheeso

Reputation: 192637

System.Diagnostics.ConditionalAttribute and conditionally compiling supporting types and variables

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

Answers (1)

Marc Gravell
Marc Gravell

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

Related Questions