Do not name a class the same as its namespace, Part Two

(This is part two of a four part series; part one is here, part three is here.)

Part Two: Machine-generated code:

You write

namespace Foo
{
public sealed class Foo
{
public string Blah(int x) { … }
}
}

You take this code and run a third-party “decorator” tool over it that makes your class into a more colourful class:

// Machine-generated code:
namespace Foo
{
public sealed class ColorFoo
{
public ColorFoo(Foo.Foo foo, System.Drawing.Color color)
{
innerFoo = foo;
innerColor = color;
}
private Foo.Foo innerFoo;
private System.Drawing.Color innerColor;
public System.Drawing.Color Color { get { return innerColor; } }
public string Blah(int x) { return innerFoo.Blah(x); }
}
}

And maybe some other stuff in there like an implicit conversion to or from Foo, and so on. The exact details of the decorator aren’t important here; what’s important is that this code was generated by a machine.

The authors of the code generator thought they were being clever and fully qualifying all the type names, but they were not clever enough. Those type names should actually be fully qualified with “global::” on the front of all of them. The code as it stands will not compile; it gives the incredibly unhelpful message “type name Foo does not exist in Foo.Foo”. 

Uh, what? It sure looks like a type named Foo exists in Foo… oh, wait. Inside namespace Foo, the name “Foo.Foo” means “the thing named Foo inside type Foo”, and we’re inside namespace Foo.

It’s ironic, like good advice that you just didn’t take: the code generator writers would have been better off not qualifying the names in this case.

Now the user is again in a cleft stick not of their own devising; the code is machine-generated and probably cannot easily be edited because its just going to be re-generated again later and the edits will be lost. 

Now, you might say, well, this is a bug in the code generator. There exist such code generators; I actually wrote this bug into a code generator once, though fortunately I realized my mistake before we shipped. It’s really easy to do, and lots of existing code generators do not fully qualify their type names all the way out to “global::”. (*)

But still, better to not cause trouble for code generators in the first place; you can avoid the problem by not naming the class and the namespace the same thing.

This scenario happens surprisingly often. Our own testers have rediscovered this one independently several times when they’ve been doing testing on code generators, and often believe it to be a bug in the compiler’s type lookup algorithm, not a flaw in the code generator.

Next time: how to design a bad hierarchy

*************

(**) And of course many code generators were written in the C# 1.0 days before the “global::” syntax was invented.

(This is part two of a four part series; part one is here, part three is here.)