FrostyStraw
FrostyStraw

Reputation: 1656

Is System.Collections a "namespace of the System namespace"?

Okay, so I've been reading a book on C# and .NET, and while learning about the DateTime structure and the following code:

DateTime dt = new DateTime(2015, 10, 17);

I asked myself "why didn't I have to reference it at the top by writing using System.DateTime"?

So I realized that since DateTime is a structure, and the "using" keyword is used to reference types (type being a general term to refer to a member from the set {class, interface, structure, enumeration, delegate}), defined in a particular namespace (in this case, DateTime is of type structure from the System Namespace).

But I noticed that at the top of my file, the following using directives are found (they were put there automatically when I created my C# console application):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

I was wondering why the using directives that follow using System were necessary, when aren't they all under the System namespace and therefore they should already be referenced?

So I'm guessing it's because all the ones declared below it are namespaces, as opposed to a type from the set {class, interface, structure, enumeration, delegate}. But would it be wrong to refer to them as "namespaces OF (or belonging to) the namespace System," and if so, what is the reason that you must explicitly reference namespaces of a namespace instead of them being implicitly included under using System?

I hope my question was clear but if not, please let me know so I can edit it.

Upvotes: 25

Views: 1823

Answers (4)

Josh
Josh

Reputation: 697

You don't have to have other using directives, e.g. if you wanted a List you could just declare in your code:

System.Collections.Generic.List<String> listOfStrings = new System.Collections.Generic.List<String>;

To create a new List, but the using statement lets you simply declare it as:

List<String> listOfStrings = new List<String>;

The reason you can't do the latter with only:

using System;

Is because there could be a class in System called List, as well as the List class in System.Collections.Generic. If so, when you create a new list object, how does it know which List class you're referring to?

So essentially they're used to prevent naming conflicts, and to enable programmers to group things into logically named groups, e.g. input and output related classes can be found in System.IO

Upvotes: 2

Steve Cooper
Steve Cooper

Reputation: 21480

Internally, all .net types always have full type names;

System.DateTime
System.Collections.Generic.Dictionary<string, int>
System.Threading.Tasks.Task

what the 'usings' do is to let you refer 'invisibly' to everything before a '.' character. So when you write

DateTime

C# will try

System.DateTime
System.Collections.Generic.DateTime
System.Linq.DateTime
System.Text.DateTime
etc...

Since only one exists (System.DateTime) it's an unambiguous match, and C# knows what you're talking about.

If there were two matches, you'd get a compiler error about the ambiguity. So if there were a System.Threading.Task.DateTime, your program wouldn't compile.

All this sets the scene for the answer to your question. If

using System;

included everything below it, then it would be hard to ensure that things aren't ambiguous. For example, if you wanted to differentiate between two theoretical classes

System.WebPages.Button
System.Desktop.Button

then a plain old using System wouldn't play nice with new Button().

Upvotes: 24

rory.ap
rory.ap

Reputation: 35280

The reason is that if it weren't that way, you'd have no way of avoiding unwanted name collisions in certain circumstances. For instance, if you had a type Baz in Foo namespace and a type Baz in Foo.Bar namespace, you'd always have to fully-qualify your types, e.g. Foo.Baz or Foo.Bar.Baz, in your code, which would make the using directives pointless.

Given the way it is, you only have to deal with name collisions if you actually have using directives for both namespaces that contain your type.

Upvotes: 3

Charles McIntosh
Charles McIntosh

Reputation: 661

Create a using directive to use the types in a namespace without having to specify the namespace. A using directive does not give you access to any namespaces that are nested in the namespace you specify.

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

The same thing happens when I am assigned namespaces cause of my folder structure like projectName\Code\DBFiles if I do using Code; on one of my controllers it doesn't give me access classes in DBFiles that's why I set all my class name spaces to the root namespace.

Upvotes: 1

Related Questions