Wednesday, August 29, 2007 12:00 AM
bart
Visual Basic 9.0 Feature Focus - Partial Methods
Welcome back to the Visual Basic 9.0 Feature Focus blog series. In this post, we'll cover Partial Methods, a feature also available in C# 3.0 (see here). Partial methods are a logical extension to partial classes, a feature that was introduced in the VB 8.0 and C# 2.0 "Whidbey" wave. As you know, partial classes are often used in code generation circumstances, like the Windows Forms designer that puts code in a *.Designer.vb or *.Designer.cs file, while the code written by the developer is written in the other part of the partial class and kept in another code file (click to enlarge and notice the classes are declared as Partial):

Most likely you're aware of the fact that you should keep yourself from modifying an generated code whatsoever, since the code generator could (and will) overwrite your changes. That's why partial classes were introduced in the first place, to keep a nice separation between the code generator's stuff and your own stuff (event handlers etc in case of Windows Forms apps). In LINQ, we do have code generators too. For example the LINQ to SQL designer is responsible to generate entity classes and a data context object that can be used to write queries against the underlying data source. However, what if you'd like to add some stuff to the generated entity classes? No problem with partial classes, except for a few scenarios. Consider the following fragment to be auto-generated:
'Generated code
Partial Class Product
Private _name As String
Public Property Name As String
Get
Return _name
End Get
Set (ByVal value As String)
_name = value
End Set
End Property
End Class
Sure, in the another part of the partial class you can add members to this class if you'd like to do so. But what if you want to change some aspect of a member that's already there? Say you'd like to write a business rule that is executed every time the name of a product is changed. You can't change the generated code since it can be overwritten by the code generator subsequently. We're in troubles indeed. What the code generator could do however is something like this:
'Generated code
Partial Class Product
Private _name As String
Public Property Name As String
Get
Return _name
End Get
Set (ByVal value As String)
SendNameChanging(value)
_name = value
End Set
End Property
End Class
However, there's no such thing as a method called SendNameChanging. In VB 8.0 and C# 2.0 such code would require this method to be present in either the generated code file (which is unlikely to be possible since an entity generator or any other code generator doesn't know about what kind of "extensions" the developer might want to add) or in another part of the partial class definition (i.e. require the developer to write such a method for each and every generated property, even if these are not required in the particular scenario the developer is faced with). The solution? Partial methods. Assume the following piece of generated code:
'Generated code
Partial Class Product
Private _name As String
Public Property Name As String
Get
Return _name
End Get
Set (ByVal value As String)
SendNameChanging(value)
_name = value
End Set
End Property
Private Partial Sub SendNameChanging(ByVal value As String)
End Sub
End Class
In here we do have a partial method declaration. All partial methods are Private (only usable inside the same class) and marked with the Partial keyword. This is the declaration of the partial method. Now, if you'd like to implement some business rule that's triggered whenever the name of a product is changing, you can put an implementation for this method in another part of the Product partial class:
'Developer's code
Partial Class Product
Private Sub SendNameChanging(ByVal value As String)
Console.WriteLine("Product name is changing to {0}", value)
End Sub
End Class
Notice at the implementation side there's no Partial keyword on the method signature (which is different from the C# 3.0 syntax). It's important to remember that an implementation of a partial method is not required. Only if you're interested in the "extension" provided by a given partial method, you should write such an implementation. If no implementation for a partial method is found, each call to that method is ignored by the compiler, hence optimizing the code. So, if you do write an implementation the above is equivalent to:
Class Product
Private _name As String
Public Property Name As String
Get
Return _name
End Get
Set (ByVal value As String)
SendNameChanging(value)
_name = value
End Set
End Property
Private Sub SendNameChanging(ByVal value As String)
Console.WriteLine("Product name is changing to {0}", value)
End Sub
End Class
while the following is produced when there's no implementation for SendNameChanging:
Class Product
Private _name As String
Public Property Name As String
Get
Return _name
End Get
Set (ByVal value As String)
SendNameChanging(value)
_name = value
End Set
End Property
End Class
So, if you don't write a partial method implementation, you don't pay any price for the method.
Happy coding!
Del.icio.us |
Digg It |
Technorati |
Blinklist |
Furl |
reddit |
DotNetKicks
Filed under: VB 9.0