Tom Goff's .Net Musings

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

Archive for November 2007

TOTW: Screen Capturing

leave a comment »

Maintaining a blog means I have to take screen shots every so often to illustrate a point. I have been using Jing, which is a free tool provided by TechSmith. In case you don’t know, TechSmith makes a commercial screen capture application called SnagIt. Recently, TechSmith decided to give away free licenses to older versions of SnagIt with the hopes you will upgrade. SnagIt has a lot of cool and very useful features. I’d highly recommend you check it out.

Another notable and free screen capture utility is Cropper (now on CodePlex), by Brian Scott.

Written by Tom

November 27, 2007 at 4:00 pm

Posted in Tip of the Week

The Catch with VS 2008 Multi-Targeting Support

leave a comment »

With the recent release of Visual Studio 2008, I have been trying to tinker with the new features when I have time. One of the features I especially like is the Multi-Targeting Support. You may have read about it before, but if not check out this blog. Using this feature, I could then benefit from the bug fixes, speed improvements, pretty interface changes, etc in Visual Studio 2008 with only minor changes to my applications. Unfortunately, there is a small catch.

If you read Scott Hanselman’s blog, then you may have read this entry. In order to install Visual Studio 2008, you obviously must install .Net 3.5 (which is all part of the Visual Studio setup). In order to install .Net 3.5, you must install .Net 3.0 SP1 and .Net 2.0 SP1. As Scott describes, there are new properties/methods that are added to the .Net 2.0 framework as part of SP1.

So if you develop an application that targets .Net 2.0 in Visual Studio 2008 and use one of the new methods or properties, then obviously your application will not run on a computer with .Net 2.0 RTM. Since the assembly versions from the RTM and SP1 are the same, your application will load the RTM assemblies and then throw an exception when it can’t find the required method or property. If you do not use any of the new properties or methods, then your application will run on a computer with .Net 2.0 RTM. In addition, you could simply apply the .Net 2.0 SP1 to the target computers.

There are a few ways to determine if a property, method, or class is new. The first is obviously the documentation. For example, the INotifyPropertyChanging interface is new to .Net 2.0 SP1 and you can see that .Net 2.0 is not included in the “Version Information” section at the bottom. The second option is to use a new optional FxCop rule (as described here) to flag items. Finally, you can test your assemblies on a computer with .Net 2.0 RTM. This last step really requires that you perform full test coverage of your assembly though.

Written by Tom

November 27, 2007 at 3:33 pm

Posted in .Net, C#, Gotcha, Visual Studio

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

TOTW: Avoid Unnecessary EventArgs Allocations

leave a comment »

In a previous blog entry about the generic EventHandler delegate, I included an example similar to the following 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>
    private 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;
        }
    }
}

In general, most developers would include additional overloads of the OnSomeEvent method to make their lives easier. For example, the following overload of OnSomeEvent allows you simply provide the “what happened” text and the method handles everything else.

/// <summary>
/// This method is used to fire the <see cref="E:SomeEvent"/>
/// event.
/// </summary>
/// <param name="whatHappened">What happened.</param>
private void OnSomeEvent(String whatHappened) {
    OnSomeEvent(this, new MyCustomEventArgs(whatHappened));
}

The problem with the code above is that a new instance of MyCustomEventArgs is allocated even if SomeEvent is null. Eventhough, nobody is subscribing to the SomeEvent event, we are performing a memory allocation.

We can update our overload so that the memory allocation is only performed if someone is actually subscribing to the event.

/// <summary>
/// This method is used to fire the <see cref="E:SomeEvent"/>
/// event.
/// </summary>
/// <param name="whatHappened">What happened.</param>
private void OnSomeEvent(String whatHappened) {
    if (null != SomeEvent)
        SomeEvent(this, new MyCustomEventArgs(whatHappened));
}

Now, the allocation of MyCustomEventArgs is only performed if it’s needed. If this event is fired often and typically does not have any handlers hooked up, then we can remove any unneeded burdon on memory and the garbage collector. 

With the example above, the OnSomeEvent methods are private. If you are expecting your class to be extended, then you may want to make OnSomeEvent(Object, MyCustomEventArgs) protected/public and virtual. This allows derived classes to customize the behavior of the SomeEvent event. If we change OnSomeEvent(String) so that it calls the event directly (instead of calling OnSomeEvent(Object, MyCustomEventArgs)), then dervied classes would have to override this overload as well. If OnSomeEvent needs to be virtual, then it’s probably best not to make the change described here.

Written by Tom

November 1, 2007 at 7:49 am