Using partial classes for cleaner, more maintainable code

Frequently you'll write classes that represent a concept that is also described elsewhere. For example, you'll have a class that represent a row in a table, a service the web or the graphical design of a form. These external concepts have descriptions which can be consumed by machines, for example through SQL metadata queries or through XML descriptions of structure or services.

It's often handy to generate the code from these descriptions. For example, I can query a database to find out the columns a table has, and then create a class with one field per column. I can then create instances of this class to represent and manipulate rows. Handy-dandy, except that now I run into a problem when I want to re-run this code generate process: if I overwrite the existing files, I'll lose whatever changes I made by hand since the last generation.

C# has a nice feature that helps with this: partial classes. When you add the partial keyword to a class, you're telling the compiler "there might be additional things defined for this class in another file". Note that you can't use partial to split code between assemblies or anything funny - it's just compiler magic, and at the end of the day it's a lot like copy-pasting the contents from one file inside another.

Let's see an example. Let's say I have a file cs1.cs, which contains structure that I mapped from somewhere, perhaps a table in a database or some known arrangements of keys in the registry.

namespace

CsNamespace
{
  public partial class Cs
  {
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
}

Now, let's say that I want to also add a "calculated field" to this, FullName. And while I'm at it, I also want to turn this class into an assembly entry point, so I can just compile the class and have a program. I can write the following file and save it as cs2.cs.

namespace

CsNamespace
{
  public partial class Cs
  {
    public string FullName
    {
      get { return this.FirstName + " " + this.LastName; }
}

    public static void Main(string[] args)
{
Cs instance = new Cs();
instance.FirstName = "Marcelo";
instance.LastName = "Lopez Ruiz";
System.Console.WriteLine(instance.FullName);
}
}
}

This will now work just fine when compiled together.

> csc.exe /out:cs.exe cs1.cs cs2.cs
...
> cs.exe
Marcelo Lopez Ruiz

You can read more on partial classes on MSDN.

Enjoy!