.NET provides an ever-increasing number of ways to extend, coordinate, modify and abuse classes. We have partial classes, extension methods, helper classes, inheritance, and wrapper classes. When should you choose one over another?
When we look through the lens of SOLID development, particularly the Single Responsibility and Open/Closed Principles, the choice becomes less bewildering.
In this post, we will consider partial classes.
A partial class is one that may be split across more than one source file (but in the same assembly). If you declare your class to be partial, then other developers can extend it by declaring a partial class with the same name, in a different file.
This sounds like the coolest thing ever until you realize that these future developers will have access to every private member of your original "part." By granting this privilege, you are promising that you will never make a breaking change even in your private members. That’s huge!
Even if you are willing to tie your own hands in this way, suppose another team member is later assigned modify your original part of the class. The fact that it is partial might not be uppermost in his mind and he could easily make a breaking change. This courts disaster, does it not?
Microsoft’s C# Programming Guide suggests that "when working on large projects" a partial class "is desirable" because it "enables multiple programmers to work on it at the same time." I say that’s solving the wrong problem the wrong way. If a class is so large that multiple programmers are routinely bumping into each other, it probably violates Single Responsibility Principle and should be refactored. Second, the source-merging capabilities of any version-control system already solve the multiple-programmer problem quite nicely.
Their other desirable scenario is "when working with automatically generated source code." When I have used the auto-generated classes of the Entity Framework, for example, I have indeed been grateful that they are partial. It shows a certain humility on the part of the code-generation author: "I am going to generate this class for you, but I admit I may not have thought of everything. I’ll make it partial so you can tweak it." However, one gets the impression (especially when working with the early versions of the Entity Framework) that the humility is all to warranted. One suspects that as the technology matures the need for partial classes will diminish and even disappear. Remember the very early days of WinForms, when it was common to modify the generated code? We don’t do that anymore, do we!?
The Open/Closed Principle states that a class should be open for extension but closed for modification. Partial classes are exactly the opposite. They are wide-open invitations for modification. Worse, they can be modified in secret, as it were, because the modifications can be in a different source file.
In short, I would discourage partial classes as a design element. They may have a place in code generation, but only as an admission that the generated code is not as complete as one might like.
Next time, we will consider extension methods and their older siblings, static helper classes. There, we will find much that is useful!