Dot Net Solutions
George V Place,
4 Thames Avenue
Windsor
Berkshire
SL4 1QP
Great Britain
0845 402 1752
GEO: -0.606174, 51.4843
 
 
 
 

My .NET Framework – Intro & Part 1 

Tags: Code

Intro

I’ve just started here at Dot Net Solutions after eight years at my last job. That means that nearly all my experience with .NET and Visual Studio 20xx happened at that one place, and over that time I built up quite a collection of “accessories”. Some of those were tools, utilities and plug-ins which I’m gradually tracking down and re-installing each time I reflexively go to do something and it’s not there or it doesn’t work: for instance, it turns out that “Edit with Vim” is not a standard item in the Windows Explorer context menu; nor, for that matter, does Ctrl-Shift-D add half-written summary comments in Visual Studio unless you’ve got GhostDoc installed.

I’ve also left behind a lot of home-brewed code, libraries and snippets which – as they were written during work hours – are technically owned by my previous employer, so I’m re-creating many of them from scratch. The thing I’m thrown by, though, is how many of the essential code-snippets and (extension) methods I rely on are not, in fact, part of the BCL or vanilla Visual Studio installation.

I think some of these are quite interesting, so I’m going to post about them as I go along, including some improvements I’m making as part of the rewrites and some notes about how the upcoming .NET 4.0 negates various things.

A quick note about Extension Methods and namespaces

As you probably know, extension methods are defined as static methods within static classes where the first method parameter is prefixed with “this”, which causes that method to appear as though it were part of that parameter’s type. In order for that method to be resolved by the compiler, and to appear in IntelliSense, the namespace containing the static class must be included in the using declarations in the code file. This still takes me by surprise today, especially when I’m working with somebody who is using ReSharper and who has allowed it to remove the “using System.Linq;” entry.

Anyway, when I write very broad general-purpose extension methods, I tend to use the same namespace as the type I am extending, so that the method is always available. Other times I might be creating methods which are particularly useful within another problem domain, so I’ll add the extensions to the namespace most closely related to that domain even though they’re on another type (for example, I have HtmlEncode and HtmlDecode as extension methods on String, but they’re defined in the System.Web namespace).

Part 1 – EventHandler.Raise

This was one of the first extension methods I wrote when I started using C# 3.0. Raising an event safely requires a good chunk of boilerplate code, and I don’t like writing boilerplate code. Let’s recap the learning process.

My First Event

class Foo{
    public event EventHandler SomethingHappened;
 
    private void MakeSomethingHappen()
    {
        SomethingHappened(this, new EventArgs());
    }
}

First time out, we just use the event handler as a method and marvel at the wonders of delegates. Then we discover that event handlers can be null…

Second time lucky

class Foo{
    public event EventHandler SomethingHappened;
 
    private void MakeSomethingHappen()
    {
        if (SomethingHappened != null)
        {
            SomethingHappened(this, new EventArgs());
        }
    }
}

This is better, and works 99% of the time. But there is an edge condition here involving threads (which has been well-documented elsewhere): what if, between checking whether the event handler is set and calling the event handler, another thread unsets the event handler? It could happen, so we need a new pattern…

Third try

class Foo{
    public event EventHandler SomethingHappened;
 
    private void MakeSomethingHappen()
    {
        var handler = SomethingHappened;
        if (handler != null)
        {
            handler(this, new EventArgs());
        }
    }
}

OK, this works, insofar as our local variable handler will not be null at the point when we call it. But we now have five lines of boilerplate code just to raise an event? Some mistake, surely. And this is where the helper method comes in. Prior to C# 3.0, this lived in a static “helper” class:

class Foo{
    public event EventHandler SomethingHappened;
 
    private void MakeSomethingHappen()
    {
        EventHelper.Raise(SomethingHappened, this);
    }
}
 
public static class EventHelper{
    public static void Raise(EventHandler handler, object sender)
    {
        if (handler != null)
        {
            handler(sender, EventArgs.Empty);
        }
    }
}

Here, we don’t need the “var handler = …” line because the helper method already has a local copy. (Also notice the use of the EventArgs.Empty static property, which saves the cost of instantiating a class every time a standard event is raised.)

When C# 3.0 arrived, turning the helper method into an extension method was as easy as adding the “this” keyword before the EventHandler parameter. Here’s the code for the three most commonly used Raise methods:

using System.ComponentModel;
 
namespace System
{
    public static class EventHandlerExtensions {
        public static void Raise(this EventHandler handler, object sender)
        {
            if (handler != null)
            {
                handler(sender, EventArgs.Empty);
            }
        }
 
        public static void Raise<T>(this EventHandler<T> handler, object sender, T eventArgs)
            where T : EventArgs {
            if (handler != null)
            {
                handler(sender, eventArgs);
            }
        }
 
        public static void Raise(this PropertyChangedEventHandler handler, 
object sender, string propertyName) { if (handler != null) { handler(sender, new PropertyChangedEventArgs(propertyName)); } } } }

As well as the plain one, there’s a method for EventHandler<TEventArgs>, which we’re encouraged to use for all our events (although the BCL team still create custom delegates), and an extra one for the PropertyChangedEventHandler which takes a string instead of a PropertyChangedEventArgs, so calls are simpler and more readable:

public int Number
{
    get { return _number; }
    set {
        if (_number != value)
        {
            _number = value;
            PropertyChanged.Raise(this, "Number");
        }
    }
}

More on the PropertyChanged event in the next post.

Published: 15 Jan 2010  02:56
0  Comments  |  Trackback Url  | 0  Links to this post | Bookmark this post with:        
 
 
 
 

Links to this post

No linkbacks added
 
 
 
 

Comments

No comments added yet
 
 
 
 

Post comment

Name *:
URL:
Email:
Comments:


CAPTCHA Image Validation


 
 
 
 

Related posts

- Quick: ReadOnlyDictionary - Published: 21 Jan 2010
- My .NET Framework – Part 2: Properties - Published: 19 Jan 2010