Introduction
Have you heard of partial classes? Partial classes permit defining part of a class in one place and another part somewhere else, usually in another file. Partial classes exist in part so Microsoft can hide the Visual Studio designer plumbing from you. There is nothing sinister here; it’s just easier to let the designer manage the declarations and event bindings—in the designer.vb files—and let you write your code in the .vb files. The .designer.vb file contains the partial method declaration—one half—and the .vb file you write code in contains the other half. This model is used for Windows Forms (and probably some other places).
Partial methods are defined in partial classes. Partial methods let you indicate that a private method declared in a partial class may be implemented in the other part of the partial class. Partial methods are stubbed in one place and implemented in another. The most likely scenario where partial methods will be used is in generated code. With generated code, the generator can add partial methods and if you want to insert additional behavior, you can provide an implementation for that method. If you don’t provide an implementation for the partial method, nothing happens. Providing the stub is optional.
Defining Partial Methods
I am going to contrive a possible scenario for partial methods that is not for code generators. Although using code generators is a very likely scenario for partial classes and partial methods, suppose you are laboring on a big project. Furthe,r suppose that you have some new developers and some very experienced developers. The new developers can be trusted to write simple entity classes with fields, properties—setters and getters—and basic constructors but not so much with the complicated code. Under such conditions, you provide the newbies with CodeRush and they could write tons of this basic code very quickly. Further, you could establish a pattern that says for every property setter a propertynameChanged partial method should be stubbed. It’s up to the experienced developers to focus on figuring out what, if anything, should go in these partial methods. In essence, you have provided useful work based on skill level: You aren’t asking newbies to overreach and you aren’t boring senior developers with dull code. (I like it.)
You are constrained how you define partial methods by these basic rules:
- You have to use the partial modifier on the class and the method stub.
- Partial methods have to be subroutines.
- Partial methods can be shared.
- Partial methods can have argument modifiers like ref and params.
- Partial methods must be private because they can only be used within the defining class.
Undefined partial methods are stripped out, so applying those rules to your scenario listing contains the partial class and partial in a property’s setter—implemented by your very smart but perhaps less experienced developers—and the partial method is provided in the second part.
Listing 1: A partial class and partial method demo that supports a scenario with two developers ultimately working on the same code base.
Imports System.Text.RegularExpressions Module Module1 Sub Main() Dim cust As Customer = New Customer cust.PhoneNumber = "(517) 555-1212" Console.WriteLine(cust.PhoneNumber) Console.ReadLine() End Sub End Module Partial Public Class Customer Private FPhoneNumber As String Public Property PhoneNumber() As String Get Return FPhoneNumber End Get Set(ByVal value As String) PhoneNumberChanged(value) FPhoneNumber = value End Set End Property Partial Private Sub PhoneNumberChanged(ByVal phoneNumber As String) End Sub End Class Public Class Customer Private Sub PhoneNumberChanged(ByVal phoneNumber As String) If (Regex.IsMatch(phoneNumber, _ "^((d{3})) (d{3})-(d{4})$", RegexOptions.IgnoreCase) _ = False) Then Throw New ArgumentException(phoneNumber) End If End Sub End Class
In Listing 1, the partial class Customer defines a pretty basic PhoneNumber property and a stub for the partial method PhoneNumberChanged. The second Customer class provides an implementation for the behavior using a regular expression to test whether the input string is in the correct format.
Summary
Partial methods is an extension of the partial class concept. Partials are another way to divide up where (and possibly by whom) classes and methods are defined. Support for partial methods is necessary to support generated code for LINQ, the Visual Studio designers, and may support new modalities of working together on the same codebase. (Or maybe not.)
If you find interesting ways to use partial methods, consider blogging about it. Partial methods are private methods stubbed in one place and optionally defined in another, making them easier to use than to find uses for.
About the Author
Paul Kimmel is the VB Today columnist for www.codeguru.com and has written several books on object-oriented programming and .NET. Check out his upcoming book LINQ Unleashed for C# due in Spring 2008. You may contact him for technology questions at pkimmel@softconcepts.com.
If you are interested in joining or sponsoring a .NET Users Group, check out www.glugnet.org. Glugnet opened a users group branch in Flint, Michigan in August 2007. If you are interested in attending, check out the www.glugnet.org web site for updates.
Copyright © 2007 by Paul T. Kimmel. All Rights Reserved.