Partial Classes and Code Generation
I recently read a post where the author was enthusiastic about the introduction of generics, anonymous methods, and iterators into C#, but really didn't see the utility of partial classes. It didn't seem to add any real new functionality to the framework. I have to disagree.
The main impetus for partial classes seems to be to separate code generated by the designer from regular user code. The other obvious benefits are the ability to break large classes into multiple files; this is especially useful when the classes themselves contain large nested classes or large blocks of related functionality.
The biggest benefit is when partial classes is used with computer-generated code.
For developers, who missed multiple inheritance, for example, it's now much easier to simulate it by writing a script that copies a single file, containing a partial class with an implementation of a specific interface together with state, and renaming that class to match the one to be merged.
In my development, I program almost as much in declarative "xml" as I do in C#. The xml files describes, not just dialogs, menus and other UI, but basic features of the classes, such as properties and events. The xml files are then read and transformed into C# files, which are then compiled.
My xml files have an extension .xCMD, where the CMD represent the name of the script, in my path, that will read the file as input and emit a file with extension .xCMD.cs as output. I have a recursive directory walker that scans for such xml files and invokes scripts on those files which are out-of-date.
I believe that my use of code generation makes me far more productive than developers who enter in all code manually, because the process of writing low-level code is turned over to the computer, which is infinitely faster and infinitely more precise at typing. Code generation provides a number of benefits:
- Consistency. Classes produced by the same generator produce consistent code.
- Readability. Xml data files are easier to read and more concise than code files.
- Clean class wrappers. Classes with clean interfaces wrap ugly or tedious low-level implementations. This is especially true for state machines wrappers.
- Testability and Quality. Bugs tends to be visible sooner, because they are reproduced exactly in each generated class. Fixing a bug in the generator removes all such occurences from the generated code.
- One-click regeneration. Changing the implementation of generated classes is easier because they are all rebuilt with one invocation.
- Documentation. Since the original specification is in XML and consists of high-level description, I can readily access it for the creation of documentation, use by another generator, and so on.
Another way to look at it is that I am essentially creating my own programming language through XML.
To make code generation work in prior versions of C#, one needed to build base classes from which the generated code derived from, and derived classes, if you wanted to extended the generated code. There were several unsatisfactory issues with having multiple such classes. Partial classes allevates allowing the same class to easily have manually entered and computer-generated code.