Do not name a class the same as its namespace, Part Four
(This is part four of a four part series; part three is here.)
Part Four: Making the problem worse
I said earlier that the fundamental reason for namespaces in the first place was organization of types into a hierarchy, not separation of two things with similar names. But suppose you are putting something into a namespace because you have two things that are of the same name and need to be kept separate. Suppose you reason “I’m going to put List into its own namespace because List could conflict with another class named List. The user needs to be able to qualify that.”
OK, that’s fine; put List into MyContainers then. But why would you then repeat the process and put List into a child namespace in MyContainers? The most plausible reason is that the level of disambiguation achieved so far is insufficient; some other entity named List is going to be in scope in a code region where elements of MyContainers are also in scope.
Let us posit that as our cause for creating a new namespace MyContainers, and then creating a new sub-namespace, MyContainers.X, to be the declaration space of List. What name should we choose for X? If the whole point is that something else named List is in scope somewhere that elements of MyContainers are in scope, then choosing “List” for “X” is making the problem worse, not better! Before you had two things named List in scope. Now you have three things named List, two of which are in scope. This is making it more confusing without solving the problem at hand: that there are two things named List in scope.
Any one of these four reasons is enough to avoid this bad practice; avoid, avoid, avoid.
(This is part four of a four part series; part three is here.)
Comments
Anonymous
March 18, 2010
You had me at Do Not Name a Class the Same as its Namespace, Part One.Anonymous
March 18, 2010
Do you actually see people making singleton namespaces like this? I would have to assume a 4-part series like this wasn't just brought on by a whim. This series is adapted from my review notes for a book that recommended the practice of naming a class after the namespace it is in. I figure if one professional author is doing this on purpose and has been teaching others to do so for who knows how long then potentially thousands of people could be doing it too; I'd like to counter that by spreading the word that this is a bad practice and contrary to our recommendations. (Many of the articles on this blog arise from discussions sparked by errors in books I review.) -- EricAnonymous
March 18, 2010
The comment has been removedAnonymous
March 18, 2010
While we're redundantly repeating ourselves, one of my favorites is Japanese wagyu beef. In Japanese "wa" means "Japanese" and "gyu" means "beef", so the term means Japanese Japanese beef beef. The Microsoft cafeterias used to advertize sandwiches "with au jus sauce". -- Eric Needless to say, I have a hard time deciding whether I should have Japanese wagyu beef or Mahi Mahi with my couscous when eating in my Rococo dining room. Last time I was in NY, NY, I went to a go-go bar where a girl named Mimi did the Can-Can while wearing a tutu. As for you book review notes, I hope your advice was followed. As a technical reviewer it's sometimes painful to make notes like "this sample doesn't compile", only to see the book published with the notes ignored. Irregardless, it's not too hard to imagine a world where the Regex class is in a namespace called System.Text.Regex instead of System.Text.RegularExpressions.Anonymous
March 18, 2010
I for one appreciate the series. No, I'd never commit the sin of class X within namepsace X, but the comments provoked thought about other best practices or language standards I was not fully adhering to. Something something about naming collections. Now let's all go listen to Mr. Mister.Anonymous
March 18, 2010
The comment has been removedAnonymous
March 18, 2010
For maximum vomit-inducing impact, I present you with: namespace Class { class Class { public int @int; public string @string; public class @class { public static Class Class; } } } So now we can write the following code: Class.Class.@class.Class.@string = Class.Class.@class.Class.@int.ToString(); You think I'm kidding. I saw something a lot like this on StackOverflow a few weeks ago.Anonymous
March 18, 2010
Thank you for this series. We're working on a library that our co-workers will be using for quite a few years to come and I happened to name a class the same as the namespace it was in. It took me all of about 30 minutes to change it however, as I had to fully qualify the class with its namespace, and it was getting very very annoying. Thanks for validating my thoughts that the design was wrong wrong wrong.Anonymous
March 18, 2010
I completely agree, namespace = class name = bad! BUT - I think I can see how people get nudged into this situation by the Visual Studio tooling. Naming guidelines say that you should name your assemblies "Manufacturer.Facility..." and when creating a project, using the same naming is appealing. So I might create a new project and name it "TiGra.Widget". This gives me a project file TiGra.Widget.csproj and a default namespace of TiGra.Widget. So now I go ahead and creat my Widget class, and guess what? My namespace is now the same as my class name. I always back out of this situation because it is pure evil, but see how easy it is to get nudged into this? Maybe if the tooling detected the '.' in the project name and instead of using the whole name as the namespace, just use everything before the last dot as the namespace, then instead of creating the default 'Class1', use the identifier after the last dot as the class name. Applying that rule would result in a namespace of "TiGra" and a default first class of "Widget" - probably a lot closer to what the user actually intended. Unless I'm the only one who names my projects like that of course ;-)Anonymous
March 18, 2010
The comment has been removedAnonymous
March 18, 2010
I just figured it goes without saying that I eat my Japanese wagyu beef sandwich with au jus sauce. Actually, it's funny you mention that because I think the person who first brought that "au jus" thing to my attention in 1998 was a Microsoftie from Waterloo. I don't remember his name but wouldn't it be ironic if you were him (or even knew them), don't you think? Anyway, I suppose I should say "bye-bye" and go walk my dog Fifi in the muu-muu I got from Pago Pago to the ATM machine so I can enter my PIN number to get some cash money to play Putt-Putt.Anonymous
March 18, 2010
The comment has been removedAnonymous
March 18, 2010
The comment has been removedAnonymous
March 18, 2010
Gabe trying so hard at pumping out the doubles haha "Ha ha" indeed. -- EricAnonymous
March 18, 2010
The comment has been removedAnonymous
March 18, 2010
@Pavel: Eric's other claim to internet fame was having one of the earliest websites devoted to the works of J.R.R. Tolkien. (I'm no expert on the life and times of Eric Lippert, but I have been reading through the Fabulous Adventures archives ... he's made reference to it at least once before.)Anonymous
March 19, 2010
The comment has been removedAnonymous
March 19, 2010
Aye aye, nog. Say, does anybody know what happens when a class is declared not in a namespace? The grammar of the language requires that every class be declared in one of three places: in the global namespace (which has no name), in some other namespace, or as a nested class inside some other type declaration. Therefore every class is declared in a namespace, either directly, or indirectly via its outer types. Therefore I do not understand the question; can you clarify it? -- EricAnonymous
March 19, 2010
Reminds me of that immutable generic stack implementation you did some time back during the series of articles on immutability. I used that class in a depth-first topological sorter and had to change the name to ImmutableStack<T> so that it wouldn't conflict with System.Collections.Generic.Stack<T>.Anonymous
March 19, 2010
On the topic of proper coding conventions, I could be wrong but it seems neither FxCop nor StyleCop meets my needs. Is there a way to have FxCop level of enforcement on non-compiled code? For example, ASP.NET source files, or anything that hasn't been built. StyleCop doesn't appear to be testing the same things, such as collection naming, for example.Anonymous
March 19, 2010
Obligatory mention of buffalo.Anonymous
March 19, 2010
namespace Buffalo { public class Buffalo { Buffalo.Buffalo buffalo(Buffalo.Buffalo Buffalo) { buffalo(Buffalo); } } } I think that actually ought to compile, although I haven't tried it. Infinite recursion when run, however.Anonymous
March 19, 2010
oh no it doesn't compile, needs a "return" in there. Drat.Anonymous
March 19, 2010
I was just wondering what happens to a class when you declare it without a surrounding namespace{}. It appears the answer is that it goes in the implicit global namespace. The first C# app I wrote was for .Net 1.1, and I forgot to put one of my classes in a namespace declaration. Well, it just so happened that when .Net 2.0 came out, it declared a class by the same name. When somebody ran my app on a computer with .Net 2.0 installed but not 1.1, it ran in the 2.0 CLR and got the new class of the same name.Anonymous
March 21, 2010
One of the annoying (to me that is) characteristics of VSxxxx is that when you add a folder in a project, Visual Studio defaults classes in the folder to a namespace which ends with the name of the folder. If a programmer is using the folders for physical (as opposed to namespace) organizational purposes, she/he either has to remove the folder name from the namespace of the new class or add a new using statement to include that folder. In tools/options, the programmer should be able to limit the default namespace to the project.Anonymous
March 22, 2010
John: I like this feature because the folder structure and namespaces are two independent hierarchies, but this feature is try to make them similar, which is beneficial for project "complexity". Managing one hierarchy instead of two is huge benefit.Anonymous
March 23, 2010
Is there any reason why System.Configuration.Configuration doesn't follow this rule? It's always painful to use in code. System.Configuration.Config (or something similar) would have been much better, like there isn't a System.Text.Regex.Regex for instance. My guess -- and I emphasize that this is a guess -- is that the class in question was invented before the framework design guidelines were written. -- EricAnonymous
April 01, 2010
The Los Angeles Angels ought to play nothing but doubleheaders.Anonymous
January 09, 2012
Thanks, man. I just went and renamed my static GameEngine class to GameEngineUpdator. It was originally NewellHenryClark.GameEngine.GameEngine, but now I know better, all thanks to you :DAnonymous
April 24, 2012
This does make it hard when you want namespaces like this: Doctor.Events, Doctor.Services, Doctor.BusinessObjects And then in Doctor.BusinessObjects you want a class called Doctor. Each namespace is a type of Doctor functionality, but you can't call them that and still have a Doctor class.