Correct Use Of Partial Classes

Correct Use Of Partial Classes

Photo by Ryan Hafey on Unsplash

 

Yesterday we examined the futility of using .NET partial classes to split up large classes. Stashing a massive class among several files still leaves us with – Drum Roll – an enormous class. It’s not an improvement. 

The only thing we had managed to do is sweep the elephant in the room under the carpet. The elephant has not gone away; we’ve only hidden it.

So, what’s a legitimate use for partial classes?

Partial classes are vital when we have autogenerated code we would like to extend with additional behaviour. Autogenerated? Yes. Code creating code. 

Some frameworks and tools will autogenerate code based on the structure of other entities, such as database tables. 

For example, here is the definition of a simple Book class that was generated using Entity Framework, a database Object Relational Mapper (ORM):

  //------------------------------------------------------------------------------
  // <auto-generated>
  //    This code was generated from a template.
  //
  //    Manual changes to this file may cause unexpected behavior in your application.
  //    Manual changes to this file will be overwritten if the code is regenerated.
  // </auto-generated>
  //------------------------------------------------------------------------------

  namespace LibrarySystem.SqlDatabase
  {
     using System;
     using System.Collections.Generic;
    
     public partial class Book
     {
        public int Id { get; set; }
        public string Title { get; set; }
        public string ISBN { get; set; }
        public Nullable<int> Type { get; set; }
     }
  }

Say, we’ve made a change to the Book table in the underlying database. Maybe we’ve added an Author column. Re-running the autogeneration tool in our .NET project will regenerate class Book with an Author property. Nice! 

Unfortunately, we have made a few direct modifications to the Book class too. Running the autogeneration overwrites these! Wiped out; gone. It looks like we should have read the comments at the top warning us about making changes in this file!

So does that mean we cannot make modifications to class Book without them being wiped out every time we want to align the model with the database schema? What if we wanted to add a useful helper method? If we put it in here, it would be lost?

Yes, pretty much. 

Unless…

Did you notice the partial keyword on the Book definition?

Hey, that means we can create a separate source file and add to the Book class behaviour in there. And any code in that file won’t be overwritten by the autogeneration tool. Pretty clever, right?!

Here is an example extension of the Book class:

  namespace LibrarySystem.SqlDatabase
  {    
     public partial class Book
     {
        enum Genre
        {
           None = 0,
           Adventure,
           Crime,
           Horror,
           NonFiction,
           Romance,
           SciFi,
           Thriller,
        }
     }
  }

The Genre enumeration will not be affected by regenerations of the autogenerated partial Book class. 

The partial keyword is excellent for breaking classes up into two fragments; one that regenerates via a code templating mechanism, and another that is available for manual editing.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply