Partial Classes to the Rescue
Raise your hand if you're a developer who faced the following issue or a similar one in .NET 1.x. Imagine you have a data abstraction object that represents a table in your database. Again, let's call this class Customer. What if, at a certain stage in the development process, the database changes to add a new field? There are two scenarios. The Customer class is simply a wrapper around the table and doesn't contain any logic. If so, you just run the tool that generates the class Customer automatically, replace the file and compile. If this is your situation, you're all set.
Much more likely, though, the Customer class underwent a lot of modifications and additions along the way. The generator tool called to recreate the Customer class overwrote all the changes you entered. To avoid that, you can resort to manual editing to incorporate the new field in the class in a more "controlled" and non-destructive way. This appears to be the only way out, but it's a quite tedious way, too.
In .NET 1.x, smart developers solved this issue by creating a base class CustomerBase that defined the schema of the class and was directly affected by the database schema (see Listing 1
). The class with the logicthe real Customer classderived from CustomerBase and extended it with specific behaviors and functionalities. In this way, you modified the database and regenerated the base class any time you wanted; you could put any additional logic inside the Customer class without facing the maintenance problems.
With partial classes, this is greatly simplified, as Listing 2
shows. Everything lives in the context of a single class, the Customer class, but key functionalities are neatly separated and easily modifiable. You can change the schema, and adapt the core code, without heavily refactoring the classes.
Partial Classes in ASP.NET
As a further example of the usefulness of partial classes, let's review how ASP.NET pages work in 1.x and what changes are slated for version 2.0. When a user requests page default.aspx
off an ASP.NET Web site, the back-end server environment generates a class on-the-fly, based on the source code of the default.aspx
resource. The source code for this class is temporarily saved to an internal server folder, compiled, and loaded into memory.
In ASP.NET 1.x, the dynamically created wrapper class inherits from System.Web.UI.Page (or any code-behind class in turn derived from Page) and provides a property for each declared control. Methods and properties defined in the base page must be declared as protected to be successfully resolved.
Thanks to partial classes, the new ASP.NET 2.0 class derivation model enables the page to define controls as private members. This removes a level of brittleness caused by the previous code-behind model because Visual Studio .NET was required to keep the markup declarations and code-behind file in sync within hidden and marked as inaccessible regions. With partial classes, this tool-based synchronization is no longer necessary.
Imagine you have a default.aspx
page with a button.
<asp:button runat="server" id="Send"
Any code bound to the pagefor example, the code to respond to the button clickingwill be defined in the associated default.aspx.cs
public partial class Default_aspx :
void Send_Click(object sender, EventArgs e)
In order to fully interact with the ASP.NET pipeline, the page must be completed with some system-defined code. This code completion code was inherited through OOP techniques in ASP.NET 1.x. It's added through the partial class mechanism in ASP.NET 2.0. If you take a look at the full source code of the Default_aspx
class as completed by the ASP.NET runtime, it will look like this:
public partial class Default_aspx :
// Other code here generated by the
// ASP.NET pipeline
In summary, partial classes help ASP.NET to build more easily dynamic classes that combine together user- and system-defined code.
There was a lot of tool-generated code in Visual Studio .NET 2003 and the .NET Framework 1.x. Although this code was hidden in properly created visual regions and commented to be left intact by developers, it ultimately added a level of fragility and brittleness to the overall project. Keeping code in sync is hard both for developers and for automatic tools. If there's a way to get rid of it, that way must be found and pursued. This is exactly what happens with partial classes in the upcoming .NET Framework 2.0.
Partial classes allow you to spread the contents of a class over multiple source files. This simple statement has a lot of implications and applications. It is a mechanism specifically designed to simplify the synchronization of user- and system-generated code. This is just what ASP.NET 2.0 does with page compilation and it's more or less what you can do yourself within your own applications as long as you use code generators.
Being able to split code over more files is great news as well. It makes things easier for teams to develop code in parallel and to build a lightweight form of separation between business logic and data that might suit you in more than one real situation.
As I write this, partial classes are still a beta technology. As far as ASP.NET is concerned, breaking changes exist also between Beta 1 and Beta 2. What does this mean? Partial classes are a hot new feature that certainly will have significant repercussions on the way you develop code for the .NET Framework 2.0. In this article, I outlined what appear to be the most significant of these repercussions. The final word, though, could only be said when you have the bits in your own hands.