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, http://en.wikipedia.org/wiki/Partial_class
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;
}
...
}
|
With partial classes you can divide the members across separate files. A class is identified as being a partial class via the partial keyword (or
Partial in VB), as the following code snippet illustrates:
// This portion of the partial class is defined in EmployeeProperties.cs
public partial class Employee
{
public int EmployeeID;
public string FirstName;
public string LastName;
public decimal Salary;
}
// This portion of the partial class is defined in EmployeeMethods.cs
public partial class Employee
{
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 {
/// <summary>
/// lblMessage control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
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.
| Life Before Partial Classes |
|
If you developed ASP.NET 1.x applications then you likely remember what
life was like before partial classes. Without partial classes, Visual
Studio had to embed the Web control
property declarations directly in the code-behind class. This resulted
in a hidden region within each code-behind class that defined these
properties. With partial classes
this low-level scaffolding is placed in a separate file, keeping our
code-behind class tidier, more readable, and more maintainable.
|
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. For more information on
this technique see http://msdn.microsoft.com/en-us/library/ms171896.aspx and
http://msdn.microsoft.com/en-us/library/bb882671.aspx.
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.)
See http://msdn.microsoft.com/en-us/library/bb882671.aspx for an example of using partial methods to add custom logic
to the objects LINQ to SQL auto-generates. And http://blogs.msdn.com/bethmassi/ shows a good example of using partial classes and methods to validate the
state of an auto-generated object created by LINQ to SQL in her blog entry,
http://blogs.msdn.com/bethmassi/archive/2008/02/25/simple-validation-with-linq-to-sql-classes.aspx.
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.
s:
http://www.4guysfromrolla.com/articles/071509-1.aspx#postadlink