53
votes

I have a C++ background and I do fully understand and agree with the answers to this question: Why is “using namespace std;” considered bad practice?

So I'm astonished that, having some experience with C# now, I see the exact opposite there: using Some.Namespace; is literally used everywhere. Whenever you start using a type, you add a using directive for its namespace first (if it isn't there already). I cannot recall having seen a .cs-file that didn't start with using System; using System.Collections.Generic; using X.Y.Z; etc.... In fact, if you add a new file via the Visual Studio wizard, it automatically adds some using directives there, even though you may not need them at all. So, while in the C++ community you get basically lynched, C# even encourages doing this. At least this is how it appears to me.

Now, I do understand that using directives in C# and C++ are not exactly the same thing. Also, I do understand that one of the nastiest things you can do with using namespace in C++, namely putting it in a header file, has no equivalently nasty counterpart in C# due to the lack of a concept of header files and #include.

However, despite their differences, using directives in C# and C++ serve the same purpose, which is only having to type SomeType all the time, rather than the much longer Some.Namespace.SomeType (in C++ with :: instead of .). And with this same purpose, also the danger appears to be the same to me: naming collisions.

In the best case this results in a compilation error, so you "only" have to fix it. In the worst case, it still compiles and the code silently does different things than you intended it to do. So my question is: Why (apparently) are using directives considered so unequally bad in C# and C++?

Some ideas of an answer that I have (none of these really satisfy me, though):

  • Namespaces tend to be much longer and much more nested in C# than in C++ (std vs. System.Collection.Generic). So, there is more desire and more gain in de-noising the code this way. But even if this is true, this argument only applies when we look at the standard namespaces. Custom ones can have any short name you like, in both C# and C++.

  • Namespaces appear to be much more "fine granular" in C# than in C++. As an example, in C++ the entire standard library is contained in std (plus some tiny nested namespaces like chrono) while in C# you have System.IO, System.Threading, System.Text etc. So, the risk of having naming collisions is smaller. However, this is only a gut feeling. I didn't actually count how many names you "import" with using namespace std and using System. And again, even if this is true, this argument applies only when looking at the standard namespaces. Your own ones can be designed as fine granular as you wish, in both C# and C++.

Are there more arguments? I'm especially interested in actual hard facts (if there are any) and not so much in opinions.

2
@Timo The OP is explicitly not asking about header pollution.Konrad Rudolph
I assumed it was because there's no competition for the global namespace to the same degree that there is in C++ (primarily due to the C standard library). But I await the answers of those who know best.Wyck
@ThomasWeller In C++ it's obvious. In C# consider an extensions method with Ext(this T t, long l) that is called via t.Ext(0). If you then add another namespace that contains an extension method Ext(this T t, int i), that one will be called instead. But I'm not an expert in C# (yet).sebrockm
@Franck even if I granted you that point, then the same argument applies to C++, further pushing my question of not seeing the difference between C++ and C#sebrockm
@Franck C++ will throw a compiler error at you in case of ambiguity. As well as C#.Timo

2 Answers

33
votes

Why is “using System;” not considered bad practice?

"using System;" is not universally not considered a bad practice. See for example: Why would you not use the 'using' directive in C#?

But it may be true that it is not considered quite as bad as using namespace std. Probably because:

  1. C# does not have header files. It is uncommon to "include" one C# source file into another using a pre-processor.

  2. std namespace is nearly flat i.e. almost all standard library functions, types and variables are in it (there are few exceptions such as the filesystem sub-namespace). It contains very, very high number of identifiers. To my understanding, System contains much fewer names, and instead has more sub-namespaces.

  3. In C#, there are no global functions or variables. As such, the number of global identifiers is typically quite small in contrast to C++ which does have those: Furthermore, it is typical to use C libraries (often indirectly) which doesn't have namespaces, and therefore place all their names into the global namespace.

  4. As far as I know, C# has no argument dependent lookup. ADL in conjunction with name hiding, overloading etc. can produce cases where some programs are not affected by a name conflict, while others are subtly affected, and catching all corner cases is not feasible with testing.

Because of these differences, “using System;” has lower chance of name conflict than using namespace std.


Also, namespace "importing" is in a way, a self-perpetuating convention: If it is conventional to import a standard namespace, then programmers will conventionally try to avoid choosing names from that namespace for their own identifiers, which helps to reduce problems with such convention.

If such an import is considered a bad practice, then programmers will be less likely to even attempt such avoidance of conflicts with imported namespaces. As such, conventions tend to get polarised either for or against the practice, even if weights of arguments between the choices were originally subtle.

-3
votes

However, despite their differences, using directives in C# and C++ serve the same purpose, which is only having to type SomeType all the time, rather than the much longer Some.Namespace.SomeType (in C++ with :: instead of .). And with this same purpose, also the danger appears to be theto me: naming collisions.

Yes, but you didn't export that danger (read: forcing others to deal with it), because of:

Now, I do understand that using directives in C# and C++ are not exactly the same thing. Also, I do understand that one of the most nasty things you can do with using namespace in C++, namely putting it in a header file, has no equivalent in C# due to the lack of a concept of header files and #include.

So it's rather a different category of thing.

Also, C++ is not "designed" to be developed in an IDE the same way C# is. C# is basically always written in Visual Studio with its Intellisense and whatnot. It's designed to be used that way, by the people who created it. Regardless of how many people use an IDE to develop in C++, it is not designed with that use case as an overwhelming concern.

Namespaces appear to be much more "fine granular" in C# than in C++.

Yes, that too. using namespace std and using System.Collection.Generic are incomparable.

So don't compare them!