Tom Goff's .Net Musings

Tidbits of information regarding .Net, C#, and SQL Server.

Archive for the ‘Class of the Week’ Category

COTW: ConditionalAttribute Class

leave a comment »

The ConditionalAttribute class allows you to selectively include/exclude methods or classes based on a given condition. Before we show how to use the ConditionalAttribute class, we will describe conditions and how to define them.

A condition is simply a boolean flag with a given name. If a condition is defined, meaning it has been included or set, then it can be considered true. If it is not defined, then it can be considered false. Conditions can vary depending on the current configuration (e..g Debug, Release, etc) and the platform (e.g. Any CPU, x64, x86, etc). Based on these conditions, you can selectively include/exclude sections of code in your project.

These conditions are used by the compiler to include/exclude code from the final assembly. Since the conditions are used by the complier they must be defined at compile time and are not valid after the assembly has been built. There are two ways to define conditions in Visual Studio 2005. In addition, condition can be defined using the command-line build tools.

In Visual Studio 2005, there are two standard conditions: DEBUG and TRACE. By default, Debug builds define both of these conditions and Release builds only define the TRACE condition. In addition, you can define any number of additional conditions using the Project properties or in source code. The screen shot below shows the Project properties window where conditions can be defined:

ConditionalAttribute (Debug settings)

As you can see, the DEBUG and TRACE are defined by default and you can define your own custom conditions (MYCON1 and MYCON2). If we switch to the Release build, you can see that the conditions are different:

ConditionalAttribute (Release settings)

You can define conditions in source code using the #define directive. The example below shows how to define MYCON1 and MYCON2 in source code:

#define MYCON1
#define MYCON2

using System;
//...

The #define directives must be included before any other non-directive lines, such as the using statements. If you are coming from a C/C++ background then #define are nothing new, but there is one difference from the C/C++ counterpart. The #define in C# does not assign a value, it can only be used to define conditions. In C/C++, #define could be used to define conditions (a.k.a. symbols) and a value could also be associated with it.

NOTE: If you are using the command-line build tools, then you must define the DEBUG and TRACE conditions manually (unless you are building from the project).

Now that we know how to define conditions, let’s see how we can use them. There are two ways to check for conditions: #if directive and ConditionalAttribute. We will first look at the #if directive and it’s associated directives. Assume we have the following application:

using System;
using System.Diagnostics;

namespace ConditionalTestApp {
    class Program {
        static void Main(string[] args) {
            CheckLicense();
            // ... Run application ...
        }

        static void CheckLicense() {
            Console.WriteLine("Check License called");
            // ... Check license ...
        }
    }
}

In addition, assume we do not want to check the license if we are running a debug build (for whatever reason). Then we can use the #if directive to exclude the call to CheckLicense:

using System;
using System.Diagnostics;

namespace ConditionalTestApp {
    class Program {
        static void Main(string[] args) {
#if !DEBUG
            CheckLicense();
#endif
            // ... Run application ...
        }

        static void CheckLicense() {
            Console.WriteLine("Check License called");
            // ... Check license ...
        }
    }
}

This tells the compiler that the call to CheckLicense should not be included in the final assembly. Using Reflector, we can see that the call was excluded in the final debug assembly:

ConditionalAttribute (Reflector #if)

The #if directive requires a matching #endif directive to indicate the end of the block. In addition, you can use the #else and #elif directives to provide multiple paths or sections of code. Conditions can also be undefined using the #undef directive. The #if directive supports ! (not), && (and), || (or), and other boolean operations on the conditions. When using these directives, Visual Studio is smart enough to “gray out” any code that will not be included in the current build.

ConditionalAttribute (Visual Studio #if)

The ConditionalAttribute class is really just a simplified version of the #if directive. Anything that can be accomplished with ConditionalAttribute can be accomplished using the #if directive, with one minor exception that I will describe later. Using the #if directive to replace the ConditionalAttribute would take more work (in the form of typing), and would be harder to maintain.

The ConditionalAttribute class can only be used to check for the existence of a condition. It cannot be used to check if a condition is NOT defined, as we did in the example above using the #if directive. In order to modify our application to use the ConditionalAttribute instead of the #if directive, we need to define a new condition. We will call the condition CHECKLICENSE and we will define it only for the Release build. The new condition is defined in the Project properties and the updated source code is:

using System;
using System.Diagnostics;

namespace ConditionalTestApp {
    class Program {
        static void Main(string[] args) {
            CheckLicense();
            // ... Run application ...
        }

        [Conditional("CHECKLICENSE")]
        static void CheckLicense() {
            Console.WriteLine("Check License called");
            // ... Check license ...
        }
    }
}

Now if we look at the assembly in Reflector we will see that the call to CheckLicense has been removed from the debug build.ConditionalAttribute (Reflector attribute)

You can see that the ConditionalAttribute on the CheckLicense method is visible above as well. This is the one exception I alluded to earlier. This allows you to see, after the build, under what conditions the given method or class would be included or excluded.

With both our examples above, the CheckLicense method and it’s code are still included in the final assembly. Only calls to the given method where excluded. This may be a problem if you are trying to hide sensitive debug code from your users (e.g. how to bypass licensing). You could use the #if directive to exclude the code inside the CheckLicense method. This could be done in conjunction with using the ConditionalAttribute, to exclude the method calls.

Written by Tom

December 3, 2007 at 8:16 am

COTW: DebuggerNonUserCodeAttribute Class

leave a comment »

The DebuggerNonUserCodeAttribute class allows you to specify classes, structs, constructors, properties, and methods that are not considered “user code”. Using this attribute is the same as applying both DebuggerHiddenAttribute and DebuggerStepThroughAttribute, with one notable exception.

In my previous blog entry about the DebuggerHiddenAttribute, I said

In the tool-tip above, Visual Studio implies that if ‘Just My Code’ was disabled then we would be able to step into class members that have the DebuggerHiddenAttribute. Although, in my tests this was not the case. With ‘Just My Code’ disabled, Visual Studio shows the break point as enabled, but it is never hit and I cannot step into the “hidden” method.

I was referring to the following image, which implies that I should be able to debug items marked with the DebuggerHiddenAttribute:

DebuggerHiddenAttribute 2

I found that if ‘Just My Code’ is disabled, then Visual Studio does ignore DebuggerNonUserCodeAttribute (but not DebuggerHiddenAttribute). Therefore, it’s probably better to use the DebuggerNonUserCodeAttribute in most cases, since it can be disabled by the user.

Written by Tom

November 27, 2007 at 12:29 pm

COTW: DebuggerStepThroughAttribute Class

leave a comment »

The DebuggerStepThroughAttribute[^] class allows you to specify classes, structs, constructors, properties, and methods that you do not want the debugger to step into. Unlike DebuggerHiddenAttribute[^], which we saw last week[^], you can still set break points in items that have DebuggerStepThroughAttribute specified and Visual Studio will not disable them.

This gives you the benefit of automatically stepping over items, while still allowing you to debug the item if needed. If we change our example from last week to use the DebuggerStepThroughAttribute, then we can set a break point in the GetFormat method if we suspect it has a defect.

using System;
using System.Diagnostics;

namespace ConsoleApplication1 {
    class Program {
        static void Main(string[] args) {
            PrintMessage(GetFormat(), "Hello World");
        }

        [DebuggerStepThrough]
        static String GetFormat() {
            return "MyApp: {0}";
        }

        static void PrintMessage(String format,
            params Object[] args) {
            Console.WriteLine(format, args);
        }
    }
}

For properties, this attribute can only be applied to the get and set blocks, as shown below:

// DebuggerStepThrough cannot be applied here
public Boolean MyProperty {
    [DebuggerStepThrough]
    get {
        return true;
    }
    [DebuggerStepThrough]
    set {
        // Set something
    }
}

Attributes like DebuggerStepThroughAttribute are only recommendations to the debugger and the debugger is not required to follow them. If you are using Visual Studio, then it’s a safe bet that the debugger will respect them. With that in mind, these attributes can make your debugging life easier.

Written by Tom

November 5, 2007 at 7:32 am

COTW: DebuggerHiddenAttribute Class

leave a comment »

The DebuggerHiddenAttribute[^] allows you to “hide” constructors, properties, and methods (herein referred to as class members) from the debugger. This means that if a class member has this attribute applied, then the debugger will not allow the user to step into in that class member. In addition, the debugger will not honor any break points in that class member. There is an small exception to this last point which I will describe later.

In the following console application, I have two methods in addition to Main:

using System;
using System.Diagnostics;

namespace ConsoleApplication1 {
    class Program {
        static void Main(string[] args) {
            SomeMethod();
            SomeOtherMethod();
        }

        static void SomeMethod() {
            for (Int32 i = 0; i < 1000; i++)
                Console.WriteLine(i);
        }

        static void SomeOtherMethod() {
            for (Int32 i = 1000; i < 2000; i++)
                Console.WriteLine(i);
        }

    }
}&#91;/sourcecode&#93;If I set a break point on each method (as shown below) and start debugging the application, then Visual Studio will stop execution on each method as they are called.

<a href="https://tjoe.files.wordpress.com/2007/10/debuggerhiddenattribute_1.png" title="DebuggerHiddenAttribute 1"><img src="https://tjoe.files.wordpress.com/2007/10/debuggerhiddenattribute_1.png" alt="DebuggerHiddenAttribute 1" /></a>

Clearly, this is the expected behavior. Now if we apply the DebuggerHiddenAttribute to one of the methods as shown here:

using System;
using System.Diagnostics;

namespace ConsoleApplication1 {
    class Program {
        static void Main(string[] args) {
            SomeMethod();
            SomeOtherMethod();
        }

        [DebuggerHidden]
        static void SomeMethod() {
            for (Int32 i = 0; i < 1000; i++)
                Console.WriteLine(i);
        }

        static void SomeOtherMethod() {
            for (Int32 i = 1000; i < 2000; i++)
                Console.WriteLine(i);
        }

    }
}&#91;/sourcecode&#93;Now when debugging, Visual Studio will disable the associated break point because the method is "hidden". You can also see below the reason that Visual Studio gives for disabling the break point.

<a href="https://tjoe.files.wordpress.com/2007/10/debuggerhiddenattribute_2.png" title="DebuggerHiddenAttribute 2"><img src="https://tjoe.files.wordpress.com/2007/10/debuggerhiddenattribute_2.png" alt="DebuggerHiddenAttribute 2" /></a>

Using this attribute can make debugging a bit easier. Looking at the code below, assume we set a break point on the PrintMessage call in the Main method and then want to step into the PrintMessage. Without the DebuggerHiddenAttribute on the GetFormat method, we would first step into the GetFormat method. We would then have to step out of GetFormat, then step into PrintMessage. In this example, we know that GetFormat is defect free and would not provide any useful information if it was debugged. So we can safely apply the DebuggerHiddenAttribute.

using System;
using System.Diagnostics;

namespace ConsoleApplication1 {
    class Program {
        static void Main(string[] args) {
            PrintMessage(GetFormat(), "Hello World");
        }

        [DebuggerHidden]
        static String GetFormat() {
            return "MyApp: {0}";
        }

        static void PrintMessage(String format,
            params Object[] args) {
            Console.WriteLine(format, args);
        }
    }
}

When and where to use this attribute can be tricky. If there was a defect in GetFormat (assuming there was more substantial code there), then we would not be able to debug it without removing the DebuggerHiddenAttribute.

In the tool-tip above, Visual Studio implies that if ‘Just My Code’ was disabled then we would be able to step into class members that have the DebuggerHiddenAttribute. Although, in my tests this was not the case. With ‘Just My Code’ disabled, Visual Studio shows the break point as enabled, but it is never hit and I cannot step into the “hidden” method.

If we explicitly tell the debugger to break, using the Debugger.Break[^] method, then Visual Studio will show the call to the method as the current statement. So in the following code, the call to SomeMethod in Main will be highlighted as the current statement and the code after the Debugger.Break call will not be executed yet. If you continue execution, then the code following the Debugger.Break call will be executed.

using System;
using System.Diagnostics;

namespace ConsoleApplication1 {
    class Program {
        static void Main(string[] args) {
            SomeMethod();
            SomeOtherMethod();
        }

        [DebuggerHidden]
        static void SomeMethod() {
            for (Int32 i = 0; i < 1000; i++)                 Console.WriteLine(i);             Debugger.Break();             Console.WriteLine("Some code after the break");         }         static void SomeOtherMethod() {             for (Int32 i = 1000; i < 2000; i++)                 Console.WriteLine(i);         }     } }[/sourcecode]In essence, the code is stopped at the point we called Debugger.Break. Since Visual Studio will not step into the "hidden" method, it moves up the stack to the place where the "hidden" method was called and displays that to the developer. Using the attribute can make debugger easier, but it can also hide important information if it's not used correctly. In general, I have found that simple properties (e.g. ones that simply get or set a field) benefit from this attribute.

Written by Tom

October 31, 2007 at 9:52 am

COTW: DebuggerBrowsableAttribute Class

with one comment

The DebuggerBrowsableAttribute[^] class allows you to specify which fields and properties of your classes will be displayed in the debugger view (e.g. Visual Studio’s Watch windows). The following code samples and screen-shots will illustrate how to use this attribute.

Note: This attribute is not currently supported in Visual Basic.

There are three possible settings that can be used with this attribute and they are defined by the DebuggerBrowsableState[^] enumeration. The first option is Collapsed, which is the default value if the DebuggerBrowsableAttribute is not specified. In the following class, neither the field nor the property have this attribute specified. This means it will use the Collapsed option.

public class MyClass {
    /// <summary>
    /// Initializes a new instance of the
    /// <see cref="MyClass"/> class.
    /// </summary>
    public MyClass() {
        this.items = new List<String>();
        this.items.Add("One");
        this.items.Add("Two");
        this.items.Add("Three");
    }

    /// <summary>
    /// Holds the items.
    /// </summary>
    private List<String> items;

    /// <summary>
    /// Gets or sets the items.
    /// </summary>
    /// <value>The items.</value>
    public List<String> Items {
        get {
            return this.items;
        }
        set {
            this.items = value;
        }
    }
}

When viewing an instance of this class in Visual Studio’s watch window, it will appear as shown here:

DebuggerBrowsableAttribute_Collapsed

The next option is called Never and will remove the associated field or property from the debugger’s view. In the following code, we have indicated that we do not want the debugger to display the Items property:

public class MyClass {
    /// <summary>
    /// Initializes a new instance of the
    /// <see cref="MyClass"/> class.
    /// </summary>
    public MyClass() {
        this.items = new List<String>();
        this.items.Add("One");
        this.items.Add("Two");
        this.items.Add("Three");
    }

    /// <summary>
    /// Holds the items.
    /// </summary>
    private List<String> items;

    /// <summary>
    /// Gets or sets the items.
    /// </summary>
    /// <value>The items.</value>
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    public List<String> Items {
        get {
            return this.items;
        }
        set {
            this.items = value;
        }
    }
}

As you can see below, the Items property is no longer shown in the watch window:

DebuggerBrowsableAttribute_Never

The final option is called RootHidden and is only useful for fields or properties that are collections or arrays. If this option is used for items that are not a collection or an array, then it will be hidden from the debugger’s view. The screen-shot below illustrates how our class would be displayed if we specified the RootHidden option for the Items property.

DebuggerBrowsableAttribute_RootHidden

As you can see, the entries that would typically be found below the Items property (by expanding the plus sign) are now merged with the other MyClass fields and properties. The RootHidden option is useful if you are writing a class that wraps a collection or array. When viewing such a class in the debugger, then you would typically drill down to the collection or array. Using this option would save you that additional step when debugging.

If you are developing .Net classes or controls for use by other developers, then you should consider using the Never option to hide private and internal fields and properties. Since the consumers of your .Net assemblies would not be able to access or modify private or internal members, then typically they would not need to see them in the debugger. Of course, there are always exceptions.

Keep in mind that these attributes are just recommendations of how you think your class should be shown in the debugger. The debugger does not have to follow them. In Visual Studio, you can choose to ignore this (and other similar) attributes by checking the configuration option shown below.

DebuggerBrowsableAttribute_VS

As with last week, this article[^] is a great resource for further reading on this subject.

Written by Tom

October 23, 2007 at 7:17 am

COTW: DebuggerDisplayAttribute Class

leave a comment »

The DebuggerDisplayAttribute[^] class allows you to specify how your classes will be displayed in a debugger. Specifically, you can define a string format that uses properties or fields from your class. This string will then be used by the debugger when it displays debug information about your class (e.g. in the Watch windows of Visual Studio).

MSDN[^] has a good write up on how to use this attribute. In the class below I have specified a string format that includes the Name property:

[DebuggerDisplay("The name of MyClass is {Name}")]
public class MyClass {
    /// <summary>
    /// Initializes a new instance of the
    /// <see cref="MyClass"/> class.
    /// </summary>
    /// <param name="name">The name.</param>
    public MyClass(String name) {
        this.name = name;
    }
 
    /// <summary>
    /// Holds the name.
    /// </summary>
    private String name;
 
    /// <summary>
    /// Gets or sets the name.
    /// </summary>
    /// <value>The name.</value>
    public String Name {
        get {
            return this.name;
        }
        set {
            this.name = value;
        }
    }
}

Assuming that I create a new instance of MyClass and pass the string “Test1” into the constructor, then Visual Studio will display this object like this:

DebuggerDisplayAttribute (1)

If you find that you often drill down in the Watch window to view a few properties of your classes, then you may want to use this attribute. If you are designing reusable classes or components, then you should definitely consider using this attribute. For further reading on this subject, this article[^] is a great resource.

Written by Tom

October 16, 2007 at 8:11 am

COTW: EventHandler Generic Delegate

leave a comment »

The EventHandler Generic Delegate[^] allows developers to easily define events without having to define a custom delegate. In the following code, MyObject defines an event which uses a custom class derived from EventArgs[^]:

public class MyObject {
    // ... Other code ...

    /// <summary>
    /// This is a custom delegate for use with the
    /// <see cref="E:SomeEvent"/> event.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The event arguments.</param>
    public delegate void SomeEventHandler(Object sender,
        MyCustomEventArgs e);

    /// <summary>
    /// This event is fired when something happens.
    /// </summary>
    [field: NonSerialized]
    public event SomeEventHandler SomeEvent;

    /// <summary>
    /// This method is used to fire the <see cref="E:SomeEvent"/>
    /// event.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The event arguments.</param>
    protected virtual void OnSomeEvent(Object sender,
        MyCustomEventArgs e) {
        if (null != SomeEvent)
            SomeEvent(sender, e);
    }
}

public class MyCustomEventArgs : EventArgs {
    /// <summary>
    /// Initializes a new instance of the
    /// <see cref="MyCustomEventArgs"/> class.
    /// </summary>
    /// <param name="whatHappened">What happened.</param>
    public MyCustomEventArgs(String whatHappened) {
        this.whatHappened = whatHappened;
    }

    /// <summary>
    /// Holds a string that tells what happened.
    /// </summary>
    private String whatHappened;

    /// <summary>
    /// Gets a string that tells what happened.
    /// </summary>
    /// <value>What happened.</value>
    public String WhatHappened {
        get {
            return this.whatHappened;
        }
    }
}

This is a typical setup for events and is the only way to define events in .Net 1.x. However in .Net 2.0 the generic EventHandler can be used to forgo the definition of the delegate. In the following code, we have removed the custom delegate and replaced it with the generic EventHandler (the class MyCustomEventArgs is exluded from the code below because it is unchanged from the previous example):

public class MyObject {
    // ... Other code ...

    /// <summary>
    /// This event is fired when something happens.
    /// </summary>
    [field: NonSerialized]
    public event EventHandler<MyCustomEventArgs> SomeEvent;

    /// <summary>
    /// This method is used to fire the <see cref="E:SomeEvent"/>
    /// event.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The event arguments.</param>
    protected virtual void OnSomeEvent(Object sender,
        MyCustomEventArgs e) {
        if (null != SomeEvent)
            SomeEvent(sender, e);
    }
}

As you can see, the EventHandler generic delegate saves us from having to define custom delegates everytime we define a new custom EventArgs class.

Written by Tom

October 7, 2007 at 8:33 pm

Posted in .Net, C#, Class of the Week