Partial Methods

About two weeks ago I had the opportunity to attend the product group dinner associated with the Global MVP Summit that was behind held here at Microsoft. Besides a free meal, this also gave me the excellent opportunity to meet with some of our MVPs and discuss their impressions with Visual Studio and all the cool new features we are introducing for Orcas. At the dinner, I had an opportunity to talk with a group of VB MVPS from Japan, who met with me and about 5 or 6 other members of the VB team. While we were talking, a couple of them asked me a few questions about partial methods. Unfortunately, I do not speak Japanese, and so had some trouble answering them. Figuring that written English may be easier to understand than my idiomatic spoken English, I decided to make Partial Methods the topic of my next blog post.

As a result, I’ve included their questions below along with my answers.

What are Partial Methods?

In a nut-shell, partial methods are a light-weight replacement for events designed primarily for use by automatic code generators. They are declared by creating a private method with an empty body and decorating it with the Partial keyword. The method may then be “re-implemented” elsewhere within its containing class. If the method is implemented, then the compiler will redirect all calls to the partial method to the implementing method. If the method is not implemented in its containing class, then the compiler silently removes any calls to it from the program. They differ from events in several ways, mainly:

A partial method can only have 1 “implementing method”, where events may have any number of handlers

The implementing method for a partial method must be in the same class as the partial method its self, where as event handlers can pretty much be defined in any type that has access to the event instance

An event will throw if it has no handlers and is invoked. Usually this requires comparing the event against Nothing to safe guard against an exception. On the other hand, if a partial method does not have an implementing method then the compiler will simply optimize away any calls to it.

The wiring of events is dynamic, which means that handlers can be added and removed from an event at runtime. This can either be done implicitly, using WithEvents variables and Handles clauses or explicitly using AddHandler and RemoveHandler statements. The wiring of partial methods, however, is always done at compile time, and an implementing method is associated with its declaring method by simply writing a method with the same name and signature as the partial method. Once this is done, all references to the partial method are rewritten by the compiler to refer to its implementing method.

Events may be declared with any accessibility (public, private, or friend). Partial Methods, on the other hand must be private. The method that implements it, however, may have any accessibility.

Here we define a class named DesignerGeneratedClass split into two partial classes. It is designed to mimic typical code generation scenarios where one partial class contains designer generated code and another contains user generated code. For example, Windows Forms classes and pages in ASP.NET Web Application Projects utilize this approach. In the designer generated file we define a utility method, DoSomething, that calls two partial method declarations OnFoo and OnBar. The user file implements OnFoo, but not OnBar. When the VB compiler processes this class, it notices this and emits a body for DoSomething() that only calls OnFoo().

What are Partial Methods useful for?

For most applications, events are almost always a better choice than partial methods due to their increased flexibility. However, there are some scenarios where they come in handy. A couple of them are listed below:

In automatic code generators

Partial methods enable code generators to write extremely flexible code by creating a lot of “hooks”, where developers can provide their own custom functionality that integrates into the “boiler plate” code created by the generator. Because the hooks are optimized away if they aren’t used, no performance penalty is introduced by defining them. This is really useful if generated code needs to be used in high performance scenarios. For example, partial methods are used by the DLINQ designer for exactly this purpose. Developers wishing to invoke custom code on their data objects when properties are set can do so without requiring all users of DLINQ to suffer performance problems.

To increase the readability of code that uses conditional compilation constants.

Consider the following code that uses conditional compilation constants in VB.Class UglyConditonalCompilationCode

No. Partial methods do share some things in common with Aspect Oriented Programming in that partial methods offer a way of associating “hooks” with custom code. However, unlike AOP systems partial methods require extension points to be explicitly defined by the customer. AOP systems allow developers to “weave in” functionality into code that hasn’t had explicit hooks defined. Usually they do this by specifying some declarative search strings that describes the places where the hooks should be applied. The compiler is then responsible for finding all the appropriate “extension points” to apply the hooks to and injecting any necessary method calls. Partial methods in VB do not do this.

Tags

Is "Partial Methods" the final name for this feature? When I heard the name I could not imagine how it worked, but I had a completely different view on it. Consider the name "Optional Method" or something else (like Partial, Optional is also a known VB name).

11 years ago

davkean

I don’t think your example is a very good example of partial methods. You can already achieve the conditional output of a method call by using the Conditional attribute (which is a lot nicer solution).

<Conditional("DEBUG")> _

Private Sub LogMessage(ByVal s as String)

Console.WriteLine(s)

End Sub

11 years ago

Nick Van Eeckhout

Will there be support for partial properties too?

11 years ago

DanielMoth

David, using the ConditionalAttribute would work for the DoStuff method but you would still have to leave the LogMessage method in your code. If you wanted to exclude the LogMethod from your code, then this approach achieves it (albeit by exchanging it for a partial method declaration).

I beleive "partial methods" is the final name for the feature. We picked it because of its close association with partial classes.

11 years ago

VBTeam

Nick,

No, there will not be support for partial properties. In general partial methods cannot have return types, so the only kind of partial properties we would be able to support would be write-only properties, which are not that useful.