I have moved!

I've moved my blog
CLICK HERE

Friday, 30 November 2007

A new use for the C# using keyword

It worries me that the using keyword doesn't have enough meanings already! But coming from a C++ background I'm very keen on the using (...) { scope } syntactic sugar. It helps with clients of IDisposable objects. But so far, it provides no help for implementors. So my suggestion is to allow the using keyword to act as a modifier on member variables.

Simple example:

class B { using FussyResource X; } 

is equivalent to:

class B : IDisposable 
{
  FussyResource X;

  public virtual void Dispose()
  {
    if (X != null)
      X.Dispose();  
  }
} 

So we can compose objects hierarchically and the IDisposable pattern is followed automatically through the hierarchy.

The using keyword in this context indicates that the outer object owns the inner object, determining its lifetime. Applying the using keyword to a type that does not implement IDisposable is an error. Of course inheritance needs to work too:

class C : B { } 

already works, because C inherits B's implementation of IDisposable. But consider:

class D : B {  using FussyResource Y; }

This needs to be translated as:

class D : B 
{
  FussyResource Y;

  public override void Dispose()
  {
    if (Y != null)
      Y.Dispose();

    base.Dispose();
  }
}

This need to override the base class's Dispose means that the base class must have a virtual Dispose. If it doesn't, then the user will not be able to take advantage of the using field modifier when they inherit from that base class.

Finally, to allow it to freely mix with existing code or to allow custom disposal in advanced cases, we also need work well alongside explicit declarations of IDisposable in the same class:

class E : IDisposable 
{
  using FussyResource X;
  IntPtr Win32Resource Y;

  public void Dispose()
  {
    Win32Helpers.FreeWin32Resource(Y);
  }
}

produces:

class E : IDisposable
{
  FussyResource X;
  IntPtr Win32Resource Y;

  public virtual void Dispose()
  {
    __Custom_Dispose();

    if (X != null)
      X.Dispose();
  }

  private void __Custom_Dispose()
  {
     Win32Helpers.FreeWin32Resource(Y);
  }
}

This could be added to C# as a pure language feature, requiring no changes to the CLR. It fits in with the existing use of using as defining a scope control the lifetime of objects. It gives C# support for implementing the IDisposable pattern that is on a par with C++/CLR. And it would mean that most of the time, writing IDisposable.Dispose by hand would be unnecessary. A little more procedural code is moved into a simple declaration.

No comments: