TypeNamesShouldNotMatchNamespaces AKA CA1724

This rule seems overly constraining. With namespaces (and the advent of the global namespace in C#) and some of the names of the nested namespaces in the FX, it seems to me this rule will generate much noise (e.g. the following nested FX namespaces are really general and could apply to many different projects/applications: Common, Services, Collections, Design, Util, Resources, IO, Configuration, Internal).

"Design" is a nested framework namespace example where the FX doesn't follow this rule, and seems to actually encourage application-defined nested "Design" namespaces.

Comments, opinions?

[641 byte] By [PeterRitchie] at [2007-12-20]
# 1

Peter,

This rule does not check to see if custom namespaces match .NET Framework namespaces, but rather if name of a type matches a .NET Framework. I would actually encourage library designers to use the same namespaces as the .NET Framework (with their product name as root though) as this enables users to easily find classes.

The names such as Common, Services, Collections, Design, Util, etc are typically too general anyway, to be used as type names.

Regards

David

DavidM.Kean-MSFT at 2007-9-9 > top of Msdn Tech,Visual Studio Team System,Visual Studio Code Analysis and Code Metrics...
# 2

The "Design" example was a bit of a rat hole, and I could have been more clear. What I'm suggesting is that namespaces in themselves reasonably guarantee fully-qualified-name uniqueness. Given that a type and a namespace are not likely interchangable, it's reasonable to expect that the namespace System.Security.Util, for example, would never be mistaken for a type such as WindowsApplication1.Util; especially once a compile takes place.

This would rear itself in a secure add-in architecture, where one assembly would contain common code for the add-ins and the loader assembly, negating the ability to use "internal".

Principal is a good example. It's both a namespace and the root name of an interface. Whenever possible, I prefer to use namespaces to contextualize my types, so if I were to implement IPrinciple I would call the type Principle (fully-qualified, it may be "Acme.Principle", instead of the rundundant "Acme.AcmePrinciple").

Util is another good example of where CA1724 warns, System.Security.Util, while a existing framework namespace, is not documented (all its types are internal, if I'm not mistaken). It would appear internal implementation of the framework is now influencing the design of 3rd party projects.

When using unique fully-qualified names, how does type names matching system namespace names affect usability?

Thanks -- Peter

PeterRitchie at 2007-9-9 > top of Msdn Tech,Visual Studio Team System,Visual Studio Code Analysis and Code Metrics...
# 3

The issue arises when users import (via an using statement for C#, or imports statement/default imports for Visual Basic) namespaces with types that contain the same name, or you need to use a namespace that contains the same name as a type or vice versa. Although you may like to fully qualify types to distinguish between these types/namespaces, other users may not and do not. However, by naming them the same as other types your forcing your consumers to do this.

Another thing to take into consideration is the lowest common denominator of your Framework. Users new to programming or .NET, may not understand how to handle type/namespace conflicts (especially as Visual Basic automatically imports certain namespaces for code file). So if you're happy not targetting this user, then simple exclude this rule.

Regarding the internal namespaces I've filed a bug internally to remove these. These definitely shouldn't be considered as conflicts.

DavidM.Kean-MSFT at 2007-9-9 > top of Msdn Tech,Visual Studio Team System,Visual Studio Code Analysis and Code Metrics...
# 4

David, I see where you're coming from.

But, I would consider the lowest common denominator to be that a developer is forced to use fully qualified type names occasionally. If naming conflicts were the root of this rule, I would expect that type name that matched any system type name would also generate a warning. Currently, no warnings are generated if I create a type with the same name as another in the framework. Yes, a list of namespaces is much easier to(possible to) maintain than a list of types. In for a penny, in for a pound--as they say.

FxCop only validates one assembly against the framework. A developer using more than one 3rd party library is likely going to run into name conflicts. I know I encounter it quite frequently, and it wouldn't have been resolved if the vendor ran FxCop on their library (if they could).

Anyway, if that's the guideline; then, that's the guideline. I'll resolve to disable it where I see fit. Removing the internal framework namespaces from the list of check namespace names would be much appreciated, as a consolation ;-).

PeterRitchie at 2007-9-9 > top of Msdn Tech,Visual Studio Team System,Visual Studio Code Analysis and Code Metrics...
# 5
For more information on the guidelines that this rule is based on, see: http://msdn2.microsoft.com/en-US/library/ms229026(VS.80).aspx.
DavidM.Kean-MSFT at 2007-9-9 > top of Msdn Tech,Visual Studio Team System,Visual Studio Code Analysis and Code Metrics...
# 6

Hi David.

I'm probably starting to sound argumentative... My original post was a comment, intended for discussion; so, I appreciate you've continued the dialogue thus far.

I re-read the Names of Namespaces guidelines and I find that it backs up my points (directly, with application-type to core-type collisions; and indirectly, in that application-type/core-type collisions seem more important than application-type/core-namespace collisions). i.e. there are the guidelines "Do not give types names that would conflict with any type in the core namespaces." (type/type) and "Do not use the same name for a namespace and a type in that namespace" (application-type/appplication-namespace) but application-type/core-namespace collisions have no explicit guideline and is only implied with annotations like "If you choose a namespace or type name that conflicts with an existing name, library users will have to qualify references to the affected items".

I completely understand that checking an application (assembly) type is very easy to check against core namespaces, since the namespace is relatively concise and stable; and, that it's much more difficult (if not very problematic) to check a type against all the externally visible core types. My feeling is that if a type/type check is not feasibly possible then a type/namespace check should be avoided. I.e. all-or-nothing.

Without trying to sound like I'm harping, CA1724 would be much more valuable if the design guidelines were established before the framework was created. As it stands, there are names in there that don't follow the guidelines (which cannot be changed or removed for backward compatibility) that cause CA1724 to fire on what should be legitimate application typenames.

-- Peter

PeterRitchie at 2007-9-9 > top of Msdn Tech,Visual Studio Team System,Visual Studio Code Analysis and Code Metrics...
# 7

Sorry for the late reply, we've discussed this internally and have come to the following conclusions and actions.

Although, after re-reading the guidelines there is no explicit guideline stipulating that a type should not be named the same as a namespace, we have decided to keep this rule. We only rip rules if they don't provide useful analysis, we feel that this rule does; naming your type 'System' or 'Windows' or 'Drawing' is just bad.

We are going to update this rule to:

  • Provide better resolutions when conflicting with a system namespaces and namespaces that exists in your assembly. For example, currently if you name your type 'System' we state: The type name 'System' conflicts in whole or in part with the namespace name 'System.Xml.Xsl.Debugger'. Change either name to eliminate the conflict. This is just bad.
  • Remove internal namespaces from the namespace list
  • Add namespaces from WinFx (Avalon, Indigo) as well as other new technologies to the namespace list

I'm not sure how establishing the Design Guidelines before the Framework was created would affect this rule. What legitimate public types is this rule firing on?

DavidM.Kean-MSFT at 2007-9-9 > top of Msdn Tech,Visual Studio Team System,Visual Studio Code Analysis and Code Metrics...
# 8
David M. Kean - MSFT wrote:
We only rip rules if they don't provide useful analysis, we feel that this rule does; naming your type 'System' or 'Windows' or 'Drawing' is just bad.
You've convinced me that the rule isn't without merits; but, I would suggest it's much more useful if it had a related rule to check for Guidelines' "Do not give types names that would conflict with any type in the core namespaces." guideline--as it's more likly to get two types with the same name confused than a type and a namespace with the same name. If all the system namespaces were adjectives, verbs or adverbs that had no homonyms or pluralised; and all classes could be nouns, this would make for a more useful rule. But, not all the system namespaces are named this way. Plus, as the system expands (i.e. WinFx namespaces, as you suggest) the likelihood that type names that were once "valid" are no longer valid because the available words for type names keeps dwindling--further increasing the likihood that this rules becomes "noise".
David M. Kean - MSFT wrote:
I'm not sure how establishing the Design Guidelines before the Framework was created would affect this rule. What legitimate public types is this rule firing on?
Namespace Principal, type IPrincipal come to mind. The Principal namespace seems mis-named (i.e. there's Identities and other things in this namespace). But, I would agree that establishing the Design Guidelines before .NET 1.0 may not have affected naming like this. System.IO.IsolatedStorage.IsolatedStorage class (brings to mind Monty Python's "Department of Redundancy Department"; but, I digress), is another namespace/class that does not follow Guidelines.

There's other namespace names that are specific to the namespace they are contained within. Xml.Schema, for example; as you know "schema" could apply to more than just XML--databases, for example. If I wanted to create a type named "Schema" (in a namespace "Database") to deal with database-related schema information and methods, I would be forced to disable CA1724 or do silly things like make the fully-qualified name "Database.DatabaseSchema".

Seems to me this rule is going to be a nightmare to maintain: You have to know which namespaces are "internal" (there's no language keyword by which to filter). Should a 2.0 namespace affect a type I define in a 1.1 application? Should upgrading from 1.1 to 2.0 cause a name comflict that wasn't a conflict in 1.1? Should special cases be introduced for pre-Guidelines naming violations. Should overly-generic, overly-overridden terms be special cased? (Design, Common, Util, Internal, Mail, Schema, Drawing, Management, etc)

I just get the feeling that this rule will cause poor namespace habits by essentially flattening the namespace of an application to include all aspects of the framework, including those not applicable to the application (e.g. a smart client's namespace would be flattened to include the Web namespace when name checking). It also seems to defeat the purpose of namespaces by flattening name checking this way.

PeterRitchie at 2007-9-9 > top of Msdn Tech,Visual Studio Team System,Visual Studio Code Analysis and Code Metrics...

Visual Studio Team System

Site Classified