LA.NET [EN]

Sep 04

Partial methods

Posted in Basics C#      Comments Off on Partial methods

In previous posts, I’ve mentioned extension methods and how you can use them for extending existing types. After talking with a friend, I’ve noticed that I didn’t mention partial methods, which are really useful for code generators. Imagine you’re writing the code generator that needs to generate C# for some specs which are defined through some sort of wizard and that you need to allow customization of some portions of that code. In the “old days”, the solution was creating virtual methods which didn’t do anything and were called by the generated C# code.

Then, the developer was responsible for creating a new class that expanded the generated C# type and for overriding the required virtual methods. Unfortunately, this technique doesn’t really work all the time. For instance, if the generator is creating a struct, you’re out of luck because structs are implicitly sealed!

Btw, and before going on, you should notice that I’ve discarded the option of changing the generated code file because we all know that, sooner or later,something will happen that will force us to regenerate the code again (leading to the lost of all customizations that have been written).

C# 3.0 (if I’m not mistaken) introduced the concept of partial method for helping with this kind of problem. Partial methods work together with partial classes for allowing the customization of the behavior of a method. Here’s a quick example:

//suppose this is generated by a tool
partial class Address{
    private String _street;
    public String Street {
        get { return _street; }
        set {
            if (value == _street) return;
            _street = value;
            OnStreetChanged();
        }
    }
    //always private!
    partial void OnStreetChanged();
}
//dev code for customizing
partial class Address {
    partial void OnStreetChanged() {
        //do your thing here
    }
}

If you wanted,the generated class could have been sealed. Now, customizing the method is as simple as creating a new partial class and implementing the desired partial method. When compared with the virtual method approach I mentioned earlier, there is an important improvement: if you don’t define a custom implementation to your method, then the method definition and call will simply be removed from the source during compilation. In other words, if there isn’t an implementation of the partial method, then the compiler won’t generate any IL for performing that call.

Before you go crazy and start creating partial methods, you should consider that:

  • they can only be declared in partial classes or structs (the next post will be about partial classes).
  • the return type of a partial method is *always* void and you cannot define any out parameters (understandable since you’re not obliged to implement the partial method).
  • a delegate can only refer to a partial method if you define it explicitly (the reason is the same as the one presented for the previous item).
  • partial methods are always private (you can’t really apply any qualifier to the method and the compiler ensures that they’re always private).

And I guess this sums it up nicely. Stay tuned for more.