Next to the big two new features shipping in Version 2.0.3 of Chrome ‘Joyride’ that we’ve already talked about in previous posts, there’s also one small but powerful new language feature that’s new as well: Partial Methods.
What are partial methods? I’m glad you asked. Partial Methods tie in with another related feature we have been supporting for a while now (are, in fact, supporting for .NET 1.1 as the only language i know of) that you are probably familiar with: Partial Classes. Partial classes allow to split the definition of a single class across multiple source files. From looking at the code, each partial looks like a complete class on its own, but at compile time, all parts will be combined into a single class. Because the separate parts form the same class, members defined in one of the parts are accessible from any part.
Partial Classes come in handy for many scenarios, the most commonly seen being the combination of one auto-generated and one user-written file, as used by the form designer, strongly typed data sets, XAML, and other technologies. One code file is generated by a tool and will usually not be touched by the user (might in fact get overwritten regularly) while the user provides a second code file to add her own members to the same class. But even in hand-written code, partial classes come in handy to split large classes into more concise section – for example our own CodeDom implementation uses separate partials to implement different aspects of the code generator – one deals with actual codegen, one contains methods relating to ASP.NET compilation, etc.
Ok, enough about classes, where to partial methods fit in?
Simple: partial methods allow one part of a partial class to define an empty method stub, without providing an implementation. Another part of the class can then choose to (or choose not to) provide an actual method body.
Let’s look at an example. A partial class generated by some tool might define the following:
type Foo = partial class private method Initialize; empty; partial; public constructor; end;
Note how the Initialize method is declared with both the empty and partial keywords. This method is a partial stub that provides no actual implementation – but still, it exists inside the class, and can be called from any of the partials. In this case, it sees likely that the constructor would probably call Initialize at some stage.
A second partial for the Foo class could now go ahead and provide an implementation for the method, by declaring
method Initialize; partial;
Note how the empty keyword is omitted this time, and a full method body will need to be provided in the implementation section – just as for any other method. Any call to Initialize() – from within either part – will then, of course, invoke the provided method implementation.
What happens if no partial provides an implementation for the method stub? Easy: any and all calls to Initialize() will be eliminated by the compiler, and it will be as if the partial method never existed. Thus, a partial method that does not provide an implementation has no runtime overhead, making partial methods an ideal candidate to provide entry points that might or might not be filled.
Now, where are partial methods used in real life?
In Chrome, there are currently two technologies that use partial methods, one shipping in 2.0.3, and one not yet.
Available now, the new Cocoa# template i wrote about before uses partial methods to expose events. Chrome provides a custom tool that generates code from a .NIB (short for NeXT Interface Builder) file that contains the User Interface definition for a Cocoa application. For any events defined in the interface, partial method stubs are provided that the developer can that provide implementations for, if he wants to handle the event. In addition, a third partial will be added to the template for 2.0.5, exposing certain standard events available system-wide from the Cocoa framework but not defined in the .NIB
Secondly, and not yet available but shipping in a future release, code generation for LINQ to SQL will rely on partial methods to provide hooks in the auto-generated code that the user can extend. Due to the zero-overhead nature of partial methods, these hooks can be provided without affecting the runtime behavior – code for them will only be executed if the user provides an implementation.
Oh, and of course there’s also full Code Completion for partial methods, showing you available (and not yet implemented) stubs: