Correct Use Of Partial Classes
Correct Use Of Partial Classes
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.
Leave a Reply
Want to join the discussion?Feel free to contribute!