Using partial classes with nested classes for maintainability

C# allows you to create nested classes - that is, classes that exist "within" a different class. Depending on what visibility you give these classes, they can be just as public as anything else (the Environment.SpecialFolder enumeration is such an example). If you use 'internal', other classes in the assembly will be able to see it, but not classes in other assemblies.

The special thing about nested classes is that you can declare them as private (the default), in which case only the containing type gets to access the class. This allows for a more controlled usage of the class, and is great for helper classes that should only be used by a single class.

One of the problems you may run into when using nested types is that if they have any reasonable size at all, it's likely that the file in which they're used ends up looking very odd - you usually end up with a much bigger file than in the rest of your project, and when you're on a method it may be difficult to tell which class the method is in. In a way, it breaks down the good advise of not having many classes in a single file.

Can you have your cake and eat it too? Of course (this would be a poor blog post otherwise I guess). Partial classes come to the rescue again. In this case we're not using them to be able to separate tool-generated from "us-"generated code, instead we're using them to separate a nested class into its own file.

To work on the previous example, let's say I have a file that declare a class Cs and uses a nested class NestedClass.

namespace

CsNamespace
{
  public partial class Cs
  {
    public static void Main(string[] args)
{
      // Here we can also refer to Cs.NestedClass as 'NestedClass'.
      NestedClass instance = new Cs.NestedClass();
instance.FirstName = "Marcelo";
instance.LastName = "Lopez Ruiz";
System.Console.WriteLine(instance.FullName);
}
}
}

Now I can include this in a separate file and compile both of them together in the same project. Note that the class I've marked as partial is Cs - in this example, I have no need to mark NestedClass as partial, as its complete definition can be found in this single file.

namespace

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

Other classes in the project will now need to "behave", and they can't break the encapsulation provided by the private nested class.

public class AnotherClass
{
  public void Foo()
{
    // Uncommenting this gives error, for example:
    //
    // error CS0122: 'CsNamespace.Cs.NestedClass' is
    // inaccessible due to its protection level
    //
    // Cs.NestedClass instance = new Cs.NestedClass();
  }
}

Enjoy!