Ever Heard of Partial Methods?
I attended an MSDN Unleashed Event here in Salt Lake City yesterday based mostly on the new bells and whistles in .NET 3.5 SP1 (and consequently Visual Studio 2008 SP1). I always enjoy the presentations from Rob Bagby, as he is entertaining to listen to and he is a let’s-dive-into-the-code, forget-about-Powerpoint-slides kind of presenter. He is a Microsoft Developer Evangelist (click Role Descriptions on the right column of the page this link references) for the Rocky Mountain states inland from the Pacific Coast. That’s just the way he rolls.
Anyway, he was trying to add some functionality to ASP.NET Dynamic Data for a demo he was showing during the event, and he mentioned a conversation he had with some of the developers at Redmond about the possibility of partial Properties. According to his words, the impression he got was that "if partial Properties were added to C#, the whole CLR would catch fire" or some other horrible catastrophe. But Rob did mention the little-known existence of partial Methods in C# 3.0, which caught my attention and sent me surfing.
See my last post about partial Classes if you want some background to partial Methods.
The genesis of this new feature is much the same as that of partial Classes, which is primarily for Classes that are auto-generated by code generators in Visual Studio (mainly associated with the numerous designers incorporated into Visual Studio). In fact, it appears the addition of LINQ may be one reason for this new feature.
Partial Methods seem to be a way to incorporate into your Classes methods that may or may not be implemented, kind of a way to stub out areas where another developer could inject specific logic they require into a pipeline of statements they didn’t write. Partial Methods can only reside in partial Classes, and can only have one declaration and up to one optional implementation. They must be private, have a void return value, and there are quite a few modifiers that cannot be used on a partial method. For a more comprehensive detailing of these restrictions (and explanations why), see this blog post by Bart De Smet that I read to learn about this new feature:
Apparently, LINQ-to-SQL makes use of this new language feature to allow the developer to plug their own business logic validation rules without modifying the auto-generated code directly. If you go to a LINQ-to-SQL generated Class, you will find a C# region named "Extensibility Method Definitions," which are partial Method declarations (see first image below). This allows you to make a separate file that is a partial Class of the LINQ-to-SQL generated class and include an implementation for one of these partial Methods, which are by default unimplemented. It appears LINQ-to-SQL allows you to plug into some of the setters of the generated object Properties that map to columns in the original SQL database table. The following images are taken from Bart’s blog post and are LINQ-to-SQL generated objects based on some of the DB structure for Team Foundation Server:
Here are some partial Method declarations in a LINQ-to-SQL generated Class called BuildCoverage:
And here is the view of the LINQ-to-SQL generated object in the designer so you can see that most of these partial Methods are based on the object’s Properties:
Here is a look at a Property setter calling these unimplemented partial Methods:
And if you wanted to implement one of these partial Methods, you get nice intellisense from Visual Studio:
And I suppose this finished implementation of the partial Method would throw a NotImplementedException after the Property has already been modified? Hopefully this is where some of that LINQ-to-SQL transactional stuff kicks in…or perhaps Bart meant to implement the OnAssemblyNameChanging partial Method instead?
This is definitely an interesting new feature in the C# language. I’ll have to keep my eye out for a really compelling use of this feature; I’m not very convinced this is the right way (or even the most common way) for using LINQ-to-SQL generated objects as if they were your Data Model objects and then insert your business logic in the above manner. Still, this is quite a thought provoking new feature.