Rules for Partial Classes
The rules for using partial classes are described here, each with its own section and a short paragraph stating the rule followed by a brief description. Of course, keep in mind that the compiler is getting better and you can experiment with the partial keyword and let the compiler be your coach.
Elements That Can Use the Partial Keyword
The partial keyword can be applied to a class, a struct (structure in VB), and an interface. All of the parts make up the whole, and you can split the parts into as many source files as you’d like.
The partial class cannot be applied to an enumeration or a delegate, although a delegate is really a class. (Oddly enough, an enumeration is modeled in the UML the same way a class is, plus the addition of the <<enumeration>> stereotype.)
Defining Parts in the Same Namespace
If you define two classes with the same name in different namespaces, the result is a different class, even if each class uses the partial keyword. For multiple parts to be part of the same whole, each part must reside in the same namespace.
Assigning Accessibility
All parts must have the same accessibility modifier. For example, if one part is public, all parts should be public. If any part has the sealed modifier applied, all parts are considered sealed. (Sealed is equivalent to NotInheritable in VB.)
Specifying Generalization and Realization
Only one part needs to provide the name of any parent classes, but all parts inherit from the same parent (this is referred to as generalization). If all parts are specific to a parent class, then all of the parts must agree.
Each part can specify different interfaces—called realization—but in the end the final type must implement (or realize the union of) all of the interfaces defined by thee parts.
Nested Partial Classes
Nested classes can be defined as partial classes even if the parent class is not defined as a partial class. What is unclear is how you would go about defining the other nested part in a separate file without defining the outer class as partial and putting that in another file as well. The help documentation seems to be silent on this topic.
In case you’ve forgotten, a nested class looks something like this:
public class Outer { // Outer’s members public class Inner { // Inner’s members here } }
The class Inner is nested within the class Outer. Declarations of type Inner could be declared by qualifying them with the Outer name, followed by the dot (.) operator and the Inner name, as in Outer.Inner. However, if Inner were defined as private, it would be inaccessible outside of Outer.
Using Attributes on Partial Types
You can apply attributes to each of the partial definitions in any manner desired. The resultant classes have the union of all of the attributes on a part.
Last Things
Finally, the partial keyword must precede one of the three words class, struct, or interface in C#, or Class, Structure, or Interface in Visual Basic.NET. All parts must reside in the same module or assembly (.exe or .dll). Generic can be defined as partial classes, but the class name and all generic parameters must match on all of the parts.
Listing 1 shows the stub of a partial class taken directly from a Windows Forms class, and Listing 2 shows the part managed by the designer.
Listing 1 This code contains the partial form class that was intended as the programmer modifier.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace MyNamespace { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } } }
Listing 2 This code contains the other part of Form1 that’s managed by the designer. It’s contained in a Form named *.designer.cs, where * is generally the class name.
namespace MyNamespace { partial class Form1 { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing "" (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.SuspendLayout(); // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(292, 266); this.Name = "Form1"; this.Text = "Form1"; this.Load += new System.EventHandler(this.Form1_Load); this.ResumeLayout(false); } #endregion } }