C# With Block

So, one of my big “beefs” with C# is the lack of support for “with” blocks. If you just want the solution to my complaints, scroll down most of the way through the article.

I come from a C/C++ background, but spent several years in the VB6 world, and came to the conclusion that with blocks are pretty handy. They do an EXCELLENT job of self-documenting the fact that you intend to do several things to a single object. They are used most frequently (for me at least) as a way of moving values from one object to another… like this:

With cmdOK
  .Top = cmdCancel.Top
  .Left = cmdCancel.Left + cmdCancel.Width + 90
End With

I wish it had support for aliasing, and using more than one with block variable at a time because I tend to use it to work with 2 objects at once… I envision something like this…

With cmdOK as btn1
  With cmdCancel as btn2
    btn1.Top = btn2.Top
    btn1.Left = btn2.Left + btn2.Width + 90
  End With
End With

You might be asking: what do you gain other than a handful of keystokes? I mean, technically, the With blocks require more keystrokes than the plain old code required in the first place.

Good point. Except the alias thing does something important. It makes it easy to copy and paste the code to do something similar someplace else, all you change is the aliases at the top, and you don’t have to worry about whether or not you found all the places where you used that variable.

It also makes it so that you can de-reference a property at the end of a long dot-chain, and give it a name that goes out of scope when you are done. For instance…

With MyApp.frmMain.cmdOK as btn1
  With MyApp.frmMain.cmdCancel as btn2
    btn1.Top = btn2.Top
    btn1.Left = btn2.Left + btn2.Width + 90
  End With
End With

That saves a temporary reference to the buttons rather than calling down the object tree with each iteration. I have often thougth that it would be convenient if you could have one with block with two aliases, like this…

With MyApp.frmMain.cmdOK as btn1, MyApp.frmMain.cmdCancel as btn2
  btn1.Top = btn2.Top
  btn1.Left = btn2.Left + btn2.Width + 90
End With

But that is (was) VB and now life is about C#. Except C# doesn’t support With Blocks – because I guess With Blocks are for wimpy programming languages.

So, I decided, wouldn’t it be interesting to create a with block construct?
Here is the best I can do:

first, you need an extension class

public static class Extender
{
    public delegate void Proc(T arg);

    public static void With(this T blockVariable, Proc block)
    { block.Invoke(blockVariable); }
}

Then, you can use it like this:

class Program
{
    static void Main(string[] args)
    {
          //using System.Xml.Linq
          XElement element1 = new XElement("hello");
          XElement element2 = new XElement("world");

          element1.With(e1 =>
          {
              e1.Add(element2);
          });
     }
}

You could even nest two or more of these with blocks…

        element2.With(e2 =>
        {
            element1.With(e1 =>
            {
                  e1.Add(e2);
            });
        });

It ain’t great, but it isn’t half bad. And, it does fulfill all of the needs I have for a with bock. It is self documenting in the sense that is says: “I intend to do several things with this object.” It also lets you assign a temporary name to a variable without creating an orphan variable that isn’t needed elsewhere in your function. And, it could be copied and pasted to do something very similar elsewhere with minimal modification (only modify the top, and the parts that need to be different in the new case).

The truth of the matter is, with extension methods and Lambda, C# really is starting to mature and get to a point where it has much of what makes Ruby and Python compelling, and, at the same time, it enjoys compile time type safety, and a powerful development environment. I dig it.

Or, you could do this (not quiet as self documenting, and a little odd, but it would work)

(new XElement("hello")).With(e1 =>
{
    e1.Add("more stuf");
    doSomethingWith(e1);
});

An object that falls out of scope immediately after the little block that uses it. This sort of move makes more sense back in vb6 when the framework actually deleted objects when they were no longer referenced, rather than let garbage collection do it later on. It would also be a bit more readable in a VB6 style With block. But the fact that it would work exactly as expected means that my C# with block is a genuine with block structure.

What do you think it will take to get the guys down at Microsoft to add With Block support to the core language? – Yeah, me neither.

Did you enjoy this post? Why not leave a comment below and continue the conversation, or subscribe to my feed and get articles like this delivered automatically to your feed reader.

Comments

No comments yet.

Leave a comment

(required)

(required)