Incorrect Use Of Partial Classes
Incorrect Use Of Partial Classes
Today’s tip deals with a feature of .NET: Partial classes.
Is see partial classes abused from time to time. If you are not aware, .NET allows us to split a class definition across multiple source files. We decorate each of the class fragment definitions with the ‘partial’ keyword. At build time, the compiler takes the various partials and fuses them back into a single class.
Why is this useful?
Generally, this is a framework feature that is handy when we are working with autogenerated code. I’ll get into the details of that next time.
Today I would like to point out a misuse of partial classes.
For example, imagine an enormous AccountController
class split across five files:
AccountController.cs
AdminAccountController.cs
UserAccountController.cs
SuperAdminAccountController.cs
OrganisationAccountController.cs
In each of these files, AccountController
is defined as a partial class:
public partial class AccountController
With about 2,000 lines per file, AccountController
contains approximately 10,000 lines of code. Each of the partials is already bloated, but the whole AccountController
class is enormous. Huge classes like this can be a real challenge to work with.
Unfortunately, breaking AccountController
up over multiple source code files obscures the actual size of the class. Programming is communication with other developers. We do not want to disguise problems – we want to highlight them, so everyone’s aware of them.
A developer who is aware that a class is already 10,000 lines long may avoid adding more behaviour to it. However, if a class appears to be only 2,000 lines long, they may not be quite so hesitant.
Splitting up a huge class by breaking it up over several files is an anti-pattern. It does not shrink the size of the class – it only appears to reduce it.
A better way is to break a large class into several smaller ones. If necessary, we can use patterns like Aggregation or Composition to reassemble the functionality into a larger whole again.
In our example, the names of the AccountController
files already indicate a breakdown by responsibilities. AdminAccountController.cs is probably the place where Admin-related AccountController behaviour resides. Similarly for OrganisationAccountController.cs and the other files.
The fix might be as simple as renaming the AccountController
class fragments to align with the file names. In the AdminAccountController.cs file, we change the declaration from
public partial class AccountController
to
public class AdminAccountController
Notice that we have removed the partial keyword. AdminAccountController
is no longer a partial class – it’s now a separate class.
Also, breaking down a large class might not always be this simple.
So, when is it appropriate to use partial classes?
There is an excellent reason to use partial classes. We’ll discover that next time.
Today’s takeaway is to avoid using partial classes to spread large classes over several files. It does not reduce class size and complexity but merely obscures it.
Leave a Reply
Want to join the discussion?Feel free to contribute!