20

Sorry if this question was asked already. I started studying C# and noticed that C# doesn't automatically import nested namespaces. I don't understand:

using System;

should automatically import all classes contained in the System namespace right? So there should be no need for me to write

using System.Windows.Form;

I would understand if using Windows.Form even worked. But the compiler could not resolve it! What is the point of the using System; before it then? So why does using System; not import System.Windows automatically as well as System.Windows.Forms - sorry if the word import is wrong here.. maybe move to global namespace is the right terminology.

Oded
  • 489,969
  • 99
  • 883
  • 1,009
Lews Therin
  • 10,907
  • 4
  • 48
  • 72
  • 5
    C# doesn't work like that, in Java you can import namespaces with wildcards, but for whatever reason the C# designers chose not to do that. I'm not sure it's constructive to debate why. – CodingGorilla Jan 26 '12 at 18:42
  • 3
    Closters - this is a legitimate question. – Oded Jan 26 '12 at 19:01
  • 2
    @CodingGorilla: The "why" is not a debate; there is a clearcut reason (i.e., as Oded said, that C# namespaces are logical, not physical groupings). – Brian Jan 26 '12 at 21:56

8 Answers8

25

C# is not Java.

A using directive is used so you don't have to type in the fully qualified name of a type. It also helps with disambiguating type names (using aliases for instance).

In the case of Console, for example, you don't need to type System.Console.

It is important to understand the difference between a namespace and an assembly - a namespace is a logical grouping of types. An assembly is a physical grouping of types. Namespaces can span assemblies.

When you reference an assembly (this is more like importing a package in Java), you gain access to all of the public types in it. In order to use a type you need to uniquely identify it. This is done through the namespace - the using directive simply means you don't have to type the fully qualified name of the type.

Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • So using will import all classes in the current namespace, but when it hits a nested namespace it ignores it? Unless I explicitly specify it.. is that the point? – Lews Therin Jan 26 '12 at 18:47
  • @LewsTherin - It's not "ignoring" it. You simply didn't specify the "shortcut". `using` directives are used so you don't have to specify the full "path" to the type. You can access the type using the full path to it if you want, but having `using` directives just ensures you don't have to type as much... – Oded Jan 26 '12 at 18:50
  • Adding a reference to an assembly means "load all types from this assembly to default AppDomain", by means of `using` directive you just tell your code which types are _visible_ at the moment. – Restuta Jan 26 '12 at 18:57
  • @Oded I think I get what you mean. So adding a reference acts like an import or #include and does a "copy and paste" into current file. But to move a class to global namespace we use using. That's where the difference lies? – Lews Therin Jan 26 '12 at 18:58
  • @Restuta - not quite. You can still use the fully qualified name of a type without a `using` directive. I would amend that comment to say "which types are _directly_ visible". – Oded Jan 26 '12 at 18:58
  • @LewsTherin - There is no "copy and paste" into current file. This is not how .NET works. An assembly can be referenced in a _project_ - this means all public types in it can be used. In a _file_ a `using` directive is used so you can call types _directly_ (without qualifying the full namespace). – Oded Jan 26 '12 at 19:01
  • @Oded and all thanks a lot. I will have to find an analogy of understanding referencing. I'm so used to #include import syntax. – Lews Therin Jan 26 '12 at 19:01
  • @LewsTherin - Glad to have been of help. – Oded Jan 26 '12 at 19:02
  • @Oded I guess it doesn't matter in this context. Yes _directly visible_ is more accurate term, but that is what normally meant when you are saying _visible_. Like person staying in front of you is visible (directly visible), but the one that is behind a wall still can be visible by using a system of mirrors (since it is in the same room). Just didn't want to confuse LewsTherin even more. – Restuta Jan 26 '12 at 19:03
  • 1
    I disagree with - `When you reference an assembly (this is more like importing a package in Java)`. Assembly in .Net is *not* equal to package in java. It is equal to Jar instead. Please see [this](http://stackoverflow.com/questions/3629291/is-a-java-package-the-equivalent-of-a-net-assembly). Namespaces in .Net are equal to packages in java. – RBT Jan 18 '17 at 01:41
13

The using directive has two uses:

To allow the use of types in a namespace so that you do not have to qualify the use of a type in that namespace:

using System.Text;

To create an alias for a namespace or a type. This is called a using alias directive.

using Project = PC.MyCompany.Project;

http://msdn.microsoft.com/en-us/library/sf0df423.aspx

However, you have to note that System and System.Windows.Form are not connected through name itself in anyway. If you import (using) System that means you will use the System assembly types in this class. Actual reference you specify in references section in Visual Studio project which you can really use (even without using statement, as this is just a shortcut for types).

Community
  • 1
  • 1
Peter Stegnar
  • 12,615
  • 12
  • 62
  • 80
  • +1. Good point - C# allows namespaces to be split across assemblies, so your project may not have imported (or want to import) the other assemblies. – TrueWill Jan 26 '12 at 18:46
  • I just realized how confused I am. I keep confusing using with import? And I assume they must be different things.. Does C# not import classes at all? I know C++ and Java does.. – Lews Therin Jan 26 '12 at 18:50
  • 1
    @LewsTherin - In .NET you add a _reference_ to an assembly which contains the types you want to "import". – Oded Jan 26 '12 at 18:53
  • @Lews Therin: Of course you should use "using" directive, because it improves readability of the code as it shorten the necessary namespace of the given type. – Peter Stegnar Jan 26 '12 at 18:57
  • Use of alias for importing a type in C# is really handy. Otherwise, just for using just one class from a namespace you import the whole namespace. It proliferates your intellisense view with whole bunch of classes present in that namespace while coding in editor. – RBT Jan 18 '17 at 01:08
10

C# doesn't import nested namespaces and this is by design.

Namespace scope lets you organize code and gives you a way to create globally unique types.

Nested namespaces are used to group related functionality, but use parts of it on-demand.

I guess you wouldn't want to have all the types from such a big namespace like System if the only thing you need is System.Windows.

So probably the question is why C# doesn't have something like using System.*; like java does. I don't know the answer, but I guess this is because of KISS principle. It's something like using

select *

you will never know what types you will add and how they will affect existing code.

Community
  • 1
  • 1
Restuta
  • 5,855
  • 33
  • 44
2

Even in Java you'd have to explicitly write

import System.*;

Much of the time you don't want all of the nested namespaces. These would simply clutter IntelliSense.

TrueWill
  • 25,132
  • 10
  • 101
  • 150
1

The "using" syntax allows you shorthand access to namespaces that are already listed as References in the project settings. If the namespace is listed as a reference you already have access to it by it's full name without the "using" directive. Just saves keystrokes.

A. Wilson
  • 688
  • 1
  • 6
  • 15
0

Let's say we have a Blazor application and the Shared folder contains UI components that we want to see on all pages so that it is convenient to use them. But if there are a lot of components, then it would be practical to group them into folders inside Shared. And in this case @global using Shared.*; would really help so you just do not understand the possibilities that this gives

Teo
  • 1
0

"Using" a given namespace means that you will get access to all definitions implemented directly in it, not that it will recursively look up the embedded namespaces; doing otherwise would defeat the purpose of the "Using" statement.

Namespaces exist to avoid class name ambiguity. The "Using" statement is here to avoid the use of fully qualified types nested in namespaces, when you know no (or little) ambiguity may occur.

Zoltan Toth
  • 46,981
  • 12
  • 120
  • 134
0

No, this is not how it works.

And I will give a good argument against what you said: intellisnse would go crazy and finding the what you want would be hell.

You do have access to everything on every namespace available (with dots), the using keyword simplifies this because you don't have to specify from which namespace a class or struct is "coming from" (I mean, defined).

Léo
  • 88
  • 1
  • 9
  • I wouldn't base a feature on your choice of editor (eg: one with intellisense). I would design a feature with only the simplest of editors in mind (eg: notepad.exe). – Thomas Eding Dec 06 '12 at 21:55
  • To avoid depending on editors, I can make a similar argument for compiler(s): compiling would be much more difficult because for everything you use that is not defined locally, it would have to check in every possible sub-tree of every module you use. Beyond difficult and wasteful, this could cause a lot of name collisions. – Léo Dec 11 '12 at 07:10