Partial Classes and the Single Responsibility Principle (SRP)

Partial classes were introduced in .Net Framework years ago. It is interesting the way it helps splitting the UI code from the domain code in two or more archives. For instance, on a Windows Forms application, there is a designer.cs archive, in which the components are declared and its properties, set. Meanwhile, the other archive (form.cs) is written by the developer without having a mixture of user interface code and business rules code. Besides, these enhancements did not exist on the beginning of the .Net Framework (version 1.0). Not all has been perfect then.

Partial classes mean to organize code, for sure, but another reason to convince you use it is help maintaining classes big enough. However, it is important to stress that in order to keep a good class design, we must resort to what Robert Martin points out with the Single Responsibility Principle (SRP): a class should have one and only responsibility. 

Although there might be many source codes referencing just one class, a concern is not to lose focus.

So, you must be wise to use this resource, because as the project grows, misorganization can make maintenance (insustentável). Separation of responsibilities is essential.

How it works, then? You may create as many .cs archives as you want. It does not matter how they are named - as long as the class declaration is named with the partial modifier. 

01.//Report1.cs
02.partial class Report
03.{
04.     public void PrintReport()
05.     {
06.        ...
07.        PrintLog();
08.     }
09.}
10. 
11.//Report2.cs
12.partial class Report
13.{
14.     bool status;
15.  
16.     private void PrintLog()
17.     {
18.        if (status == Convert.ToBoolean(PrintStatus.OK))
19.        {
20.           ...
21.        }
22.     }
23.  
24.    public enum PrintStatus
25.    {
26.      OK,
27.      ERROR
28.    }
29.}

A method that prints a report was defined on Report1.cs, whereas on Report2.cs the PrintLog method produces the document's print log.

​The compiler will combine in one archive all those archives defined as partial classes, and the intermediate language generated code is not altered as well. Not only classes may be defined by this modifier, but structs, interfaces or methods.

Other important features:

  • All parts have to be in the same solution, otherwise it will generate a compiler error;
  • It is not possible to use the private modifier in a partial type declaration;
  • The attributes and methods are accessible by the parts;
  • If a part of a partial class is abstract, then the whole class is abstract;
  • A part may implement one or more interfaces and, the other part, other interfaces. Then, a class implement all interfaces as a whole.

Thiago Vidal