Partial methods in .NET 3.5, overview and evolution

One of the interesting new things in .NET 3.5 is partial methods which are now being used extensively by LINQ to SQL and no-doubt will be Microsoft’s corner-post of extensibility for generated classes. Here’s a quick overview:

Extending generated code via inheritance (.NET 1.1)

When inheriting from generated classed designers often provide virtual methods for you to override and extend at a cost of being forced to inherit from the generated class instead of one of your own choosing. e.g.

class Customer {
    private string name;
    public string Name {
        set {
            name = value;
            OnNameChanged();
        }
    }
    protected virtual void OnNameChanged() {
    }
}

class Customer : CustomerGenerated {
    protected override void OnNameChanged() {
        DoSomething();
    }
}

Extending generated code via delegates/event handlers (.NET 2.0)

.NET 2.0 introduced partial classes and code generation moved into separate files that were pulled together at compile-time to provide a single consistent class leaving you free to choose your own inheritance.

The drawback is that you can not override generated methods because they are not inherited but rather merged at compile-time.

This means if you want to provide extensibility in your generated code you will either need to use inheritance or generate delegates/events that consumers of your class can hook up. This works but is not intuitive as demonstrated:

partial class Customer {
  protected event EventHandler NameChangedHandler;
  private string name;
  public string Name {
    set {
      name = value;
      if (NameChangedHandler != null)
          NameChangedHandler.Invoke(this, null);
    }
  }
}

partial class Customer {
  public Customer() {
    NameChangedHandler += OnNameChanged;
  }

  protected void OnNameChanged(object sender, EventArgs e) {
    DoSomething();
  }
}

Extending generated code via partial methods (.NET 3.5)

.NET 3.5 sees Microsoft answer the problem by allowing the partial keyword to be used at method level instead of just at class level:

partial class Customer {
  private string name;
  public string Name {
    set {
      name = value;
      OnNameChanged();
    }
  }
  partial void OnNameChanged();
}

partial class Customer {
  partial void OnNameChanged() {
    DoSomething();
  }
}

Thoughts

This is clearer than using delegates & events but still suffers some limitations:

  • Only one method can have a body so you can’t override generated code
  • Properties are not supported

If .NET supported multiple inheritance then partial classes and methods would be redundant. As Microsoft tout interfaces and composition as a better approach it is about time they added support to automatically wire up an interface to a compound object (a blog post for another time).

[)amien

1 responses

  1. Avatar for steve

    .Net looks more like C++ every day ;) The ability to use 'partial' on methods basically makes the non-generated code a C++ header file.

    Personally I think it overcomplicates things to mix generated and non-generated code in one class. They're trying to address the practical difficulties of doing so when in fact I think they should be avoiding it entirely.

    Version by version I see .Net become more and more complex and think each time it takes it further away from the productivity gains you get from standardising and simplifying. I've said it before but I don't think layering more complexity in the core language (as opposed to keeping it simpler and providing features through libraries) always makes the platform any more productive. C++ is less productive for business apps because it's more complex and there are a hundred ways to do something, and I do wonder whether .Net is getting ever closer to that.

    steve 2 August 2007