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