When you look at the code for the Winforms Designer, you see things like this:
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", ... etc.
instead of
using System.Drawing;
label1.Font = new Font("Microsoft Sans Serif", ... etc.
The same is true of tools like Linq to XSD, XSD2Code and, I suspect, of Linq to SQL. These tools generate hoards of code with extremely long fully-qualified names.
Wouldn’t it be easier to generate the appropriate using
statements, and ditch the long names? Or is there some technical reason for this that I’m missing?
Note: For those folks that are baffled by the notion that I might want these classes to actually be readable by a human, note that this is exactly my goal. I have an XSD with about 300 classes in it, I don’t want to write them all by hand, and yes, I’d like them to look like ordinary code written by humans.
3
Code generators explicitly declare the classes they are using to prevent unexpected behaviour from naming conflicts.
If a project includes a class with the same name as a class in another namespace, it introduces ambiguity. Where there’s ambiguity, the compiler defaults to the local namespace. Consider this:
using System.Drawing;
namespace MyProject {
class MyClass {
void InitialiseComponent() {
this.label1.Font = new Font("Microsoft Sans Serif", ...);
}
}
}
This works fine as it is. But what if we add a new Font
class to the project?
namespace MyProject {
class Font : System.Drawing.Font {
public Font(string fontName, ...) { ... }
}
}
Now we have System.Drawing.Font
and MyProject.Font
. The code in MyProject.MyClass.InitialiseComponent()
still compiles and runs. But which version of Font
does it use?
The compiler defaults to the local namespace of MyProject.MyClass
and uses MyProject.Font
, even though using System.Drawing
is defined.
Is this what the programmer wanted? It’s not the IDE’s job to guess that. The programmer should explicitly state whether they want to use their implementation of Font
or System.Drawing.Font
.
Within a single project, the IDE could detect this change and alter all code generated files to clarify which Font
to use. But what if the project isn’t currently loaded? How can the IDE know which files require future maintenance? Start by being specific and there’s never ambiguity.
4
Code generators are usually designed to create machine readable code more than human readable code. Humans are expected to mostly work with the original format used as input to the generator. using
statements enhance human readability, but computers don’t care.
Try going through the exercise of writing a simple code generator as you describe, and you’ll see why they use the fully-qualified names. Usually you make some sort of abstract syntax tree based on the original input format, then you walk the tree to generate the code. Using using
statements would require keeping an extra “registry” of using
statements you want to use, checking it for duplicates, then going back to insert them at the top of the file. That’s worth it if it’s required, like say an include
statement, but it’s a lot more trouble than it’s worth for something with an easy enough workaround.
12
If you created or imported another library that also defined Font, then without full qualification the generated code would have an error.
7
Short names and using
s are useful for humanly written code, because:
-
developers prefer writing
var defaultFont = new Font(...)
versusvar defaultFont = new System.Drawing.Font(...)
, -
other developers prefer readable code, not something with long variable names and fully qualified types.
That’s why using
s were invented in a first place. We could specify fully qualified types, but it would severely reduce code qualify.
Wouldn’t it be easier to ditch the long names in generated code? Not really; in fact, it doesn’t matter. When the code is generating other code, it makes no difference between type.Name
and type.FullName
. By using the full names, the code generator doesn’t need to prepend the using
s, making the generator easier to develop.
I noticed that you commented the answer by Karl Bielefeldt, writing:
That’s great if you can treat the generated code as a black box, and never have to modify it. That’s not always the case.
Code generators are never designed to generate clean code which would be read and modified by humans. In general, you shouldn’t modify generated code, because either you lose the ability to use the generator again, or all your modifications will be lost the next time you call the generator. Case when you do need to modify generated code by hand are rare, and it’s understandable that people writing code generators don’t take those scenarios into account.
If code generators were written for humans, they would have generated code:
-
With a few more comments,
-
Properly indented,
-
Conform to style guidelines (see yourself how many StyleCop warnings are caused by generated code for a simple Windows Forms class),
-
With clean names which don’t start with
@
character, -
Unit tested for regression testing.
This would make the code much more readable, but would also introduce potential bugs and more code to write in support when developing a code generator.
5