Regions in C# are one of those things that seem to have never quite delivered on their initial promise of giving us an another way to structure our code in addition to the constructs provided by the language.

Like many .Net developers, I once used regions extensively to structure my code, only to abandon them because of the frustration factor - the code I wanted to read was always hidden.

However, simply ignoring a language feature doesn’t seem like the smartest move. There must be a better way to use regions, a way that provides value.

I think I have found the answer.

Remember that when introduced in the original C# language, regions were used to hide generated code such as that created by the WinForms visual designer. Note also that regions are closed by default when you open a file in Visual Studio - another clue that regions should be used to hide code of lesser import.

If regions were introduced to hide boilerplate code generated by Visual Studio, perhaps we should use them in the same way: to hide the boilerplate code, the infrastructure code of lesser importance that supports the rest of the class.

To illustrate: I’m working on an M-V-VM style WPF application at the moment. To support binding between the Ribbon at the top of each window and my viewmodel, I have declared a number of properties to publish commands for binding. The code looks something like this:

public RoutableCommandSink OpenCommand
{
    get { return mOpenCommand; }
}

public ViewModel()
{
    ...

    mOpenCommand
        = new RoutableCommandSink(
            ApplicationCommands.Open,
            Open,
            CanOpen);

    ...
}

public void Open() { }

public bool CanOpen() { }

private RoutableCommandSink mOpenCommand;

Most of this code is infrastructure, present solely to support the binding between the view and the viewmodel.

To hide this code away, I’m using three regions like this:

#region Commands
public RoutableCommandSink OpenCommand
{
    get { return mOpenCommand; }
}
#endregion

public ViewModel()
{
    ...

    #region Command initialization

    mOpenCommand
        = new RoutableCommandSink(
            ApplicationCommands.Open,
            Open,
            CanOpen);

    #endregion

    ...
}

public void Open() { }

public bool CanOpen() { }

#region Command storage

private RoutableCommandSink mOpenCommand;

#endregion

For a single command, this wouldn’t make sense - but for a viewmodel containing upwards of a dozen commands, hiding this infrastructure code makes it easier to focus on the actual functionality.

Is there infrastructure in your codebase that needs hiding inside a region?

Comments

blog comments powered by Disqus