Thursday, October 7, 2010

An Overview of Partial Classes and Partial Methods By Scott Mitchell

Introduction


Partial classes and partial methods are two programming language features of .NET programming languages that make it possible for developers to extend and enhance auto-generated code. In a nutshell, partial classes allow for a single class's members to be divided among multiple source code files. At compile-time these multiple files get combined into a single class as if the class's members had all been specified in a single file. Partial methods are methods defined in a partial class that are (optionally) divided across two files. With partial methods one file contains the method signature - the method name, its return type, and its input parameters - while the body is (optionally) defined in a separate file. If the partial method's body is not defined then the compiler automatically removes the partial method signature and all calls to the method at compile-time.

Partial classes and partial methods are most commonly used in auto-generated code. The framework or tool that is auto-generating the code can create the auto-generated classes as partial classes. If the developer using the auto-generated code wants to extend the functionality of the class by adding new methods or properties she can do so by creating a new partial class file and putting her additions there. By having these additions in a separate file there's no risk of the tool overwriting the developer's changes when regenerating the code.

Regardless of whether you know the ins and outs of partial classes you use them every time you create an ASP.NET web page using a code-behind class. And if you routinely use auto-generated libraries, like LINQ to SQL or Typed DataSets, then it behooves you to be familiar with both partial classes and partial methods, as they offer opportunities for safely extending the functionality of auto-generated code. Read on to learn more about how these features work and how you can put them to work.

Splitting a Class Across Multiple Files

Partial classes allow a class's members - its methods, properties, and events - to be split across multiple files; they were introduced as language features to C# 2.0 and Visual Basic 8.0, which were the versions of the languages that shipped with the .NET Framework 2.0 in 2005.. Prior to partial classes a class would need to be entirely defined within one file, like so:

public class Employee
{
public int EmployeeID;
public string FirstName;
public string LastName;
public decimal Salary;

public void ApplyAnnualCostOfLivingRaise()
{
Salary *= 1.05M;
}

...
}

Uses of Partial Classes
Partial classes have a variety of uses:


They can be used to improve the readability of extremely large classes by partitioning related methods into separate files. (Of course, if your project has very large classes with thousands of lines of code you may want to consider refactoring that massive class into several smaller classes.)
For shops using source code control with exclusive checkouts dividing a class into separate files can reduce the likelihood of one developer being blocked from working on a class until it is checked in by another developer. And even when using non-exclusive checkouts - which is usually the preferred method - having a class spread across multiple files reduces merges.
Partial classes enable the code generator to generate code in one file while the developer who may need to extend the auto-generated logic can do so in a separate file, which eliminates the worry that the code generator might overwrite a developer's customizations.
The last use of partial classes is the most important one of the three and is one ASP.NET developers enjoy every single time we create an ASP.NET page that uses a code-behind class.

How Partial Classes Are Used In An ASP.NET Application
As you know, an ASP.NET page is typically divided into two files:


A markup file with a .aspx extension, and
A code file, with a .aspx.cs or .aspx.vb extension
The markup file contains static HTML, Web controls, and data-binding syntax. The code file contains page-level event handlers and event handlers for the Web controls defined in the markup page. Moreover, the code file can reference the Web controls defined in the markup file. This begs the question - how does the code file have access to the Web controls defined in the markup file?
If you look at the class definition in the code file you'll note that the class is marked as a partial class. Here's an example:

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
...
}
}

This code defines a partial class named _Default (or whatever the name of the page happens to be). Note that it does not contain any references to the Web controls defined in the markup portion. That is, if we had a Label Web control in the markup file with its ID property set to lblMessage we could write code in the code-behind class like lblMessage.Text = "Hello, World!" Yet there is no definition for the lblMessage Label in the code-behind class.

The Web controls defined in the markup portion are implemented as properties in an auto-generated partial class. If you are using a Web Application Project you can browse to this partial class directly by visiting the WebPageName.designer.cs or WebPageName.designer.vb file; in a Web Site Project this designer partial class file is created behind the scenes. The following code shows an example of such a designer partial class:

public partial class _Default {

///
/// lblMessage control.
///

///
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
///

protected global::System.Web.UI.WebControls.Label lblMessage;
}

The _Default class is split across two files: the auto-generated designer file and your code-behind class file. The code-behind class file can access the Web controls defined in the markup file because they are actually implemented as properties in the class itself, albeit in a separate, auto-generated file.

Partial classes are also useful with tools like Typed DataSets and LINQ to SQL, which auto-generate class files to assist with data access. It's not uncommon that you need to add additional properties or methods. Doing so involves creating a partial class and adding the needed methods or properties in that separate file.

Defining a Method Across Two Files
Partial methods allow the definition of a method to be located in one file and the body of the method to be optionally defined in another file. They can only be used in partial classes and were introduced as language features in C# 3.0 and Visual Basic 9.0, the versions that shipped with the .NET Framework 3.5 and Visual Studio 2008.

Returning to our Employee example, with partial methods we could define a partial method named

// This portion of the partial class is defined in Employee.cs
public partial class Employee
{
public int EmployeeID;
public string FirstName;
public string LastName;
public decimal Salary;

public partial void ApplyAnnualCostOfLivingRaise();

public void PerformEndOfYearProcesses()
{
ApplyAnnualCostOfLivingRaise();

...
}
}


// This portion of the partial class is defined in EmployeeAnnualCostOfLivingRaise.cs
public partial class Employee
{
public partial void ApplyAnnualCostOfLivingRaise()
{
Salary *= 1.05M;
}
}

Note that in the first file, Employee.cs, the method ApplyAnnualCostOfLivingRaise is defined as a partial method. No body is supplied, yet the method can be called from other methods in the class, as it is from PerformEndOfYearProcesses. Keep in mind that the partial method's body is optional. If the body is not supplied then when the class is compiled all references to the method ApplyAnnualCostOfLivingRaise are removed. If the body is defined, as it is in the EmployeeAnnualCostOfLivingRaise.cs file, then the compiler treats the method as if it had been defined in the same class file.

Partial methods are especially useful in auto-generated code situations. A code generating tool might now that there are certain extension points that some users are going to be interested in customizing. For example, the objects created in LINQ to SQL have partial methods like OnLoaded, OnCreated, OnPropertyNameChanging, and OnPropertyNameChanged. The auto-generated code calls the OnCreated partial method from its constructor. If you want to run custom code when one of these objects is created you can create a partial class and define the body for the OnCreated partial method. (If you do not need to add such customization then all calls to the OnCreated method are removed at compile-time.)

Conclusion
Partial classes and partial methods are language features available in C# and Visual Basic that, among other uses, provide a simple and safe way to add new functionality or extend existing functionality of auto-generated code. In short, partial classes and partial methods allow class and method definitions to be split across multiple files, which allows the code generator tool to make its writes to one file while your customizations can be made to an entirely separate file. The compiler intelligently combines the definitions together into a single class at compile-time.

Happy Programming!