Well, Bruce, it's a little simpler than that. And you would be surprised
where namespaces crop up outside of the .Net Framework and Object-oriented
programming technologies. I'm pretty good with analogies, so I'm going to
start with one.
You're in an office building, and you have an appointment to speak with
someone who works in that building. So, you walk up to the information desk,
and say "I have an appointment to speak with a person." The person behind
the desk looks at you quizically, and says, "Well, that narrows it down to
about 400 people who happen to be in this building right now. You're
reference is ambiguous. I can't identify the person you want to speak to, so
I can't help you."
So, you step back, and you remember that it is a man that you want to speak
to. So, you walk back up to the information desk and say "It's a man I need
to speak to." The fellow behind the desk laughs, and says "Well, that
narrows it down to about 200 people. Sorry."
Suddenly, you remember the fellow's first name. It's John. "John!" you
shout. "I have an appointment with John!" Now, the fellow behind the desk
scratches his head. "Nope," he says. "That's an ambiguous name reference.
There are about 50 Johns in this building." Crestfallen, you step away again
to think.
After a minute, you remember his last name. It's Smith. And then you
remember that he is in the accounting department. So, you walk confidently
to the information desk again. "His name is John Smith, and he's in the
accounting department." Now, the fellow behind the desk starts leafing
through a directory. "The accounting department is floors 7 and 8, and there
are 4 John Smiths in that department" he finally replies.
Well, that's enough for you to go and start looking for yourself. So, you
take the elevator up to the 7th floor, and start walking around, asking
everyone where "John Smith" is. But everyone replies in the same way: "Which
John Smith do you want to talk to?" You finally reply, "Any John Smith will
do. Just point me to his office."
So, after being directed to one wrong John Smith's office on the 7th floor,
and 2 wrong John Smith's offices on the 8th floor, you finally find the
right one. Of course, you're too late for your appointment. He tells you
you'll have to schedule another one for tomorrow. On your way out, you take
note of the sign on his door: "Mr.John.Smith.Accountant.Room714." And you
make sure to write it down.
When you get home, your wife is waiting for you. You don't see your son
around, so you ask her, "Where's John?" She replies, "he went to the grocery
store."
Now, why did the information desk clerk have so much trouble telling you
where to find an accountant named John Smith, but when you got home, you
simply asked where "John" was, and your wife knew exactly what and whom you
were talking about? Well, it's all about context.
The CLR, and almost any body of classes, is going to have quite a few
members in it. Class names and member names are usually designed to make
sense to humans, but it is almost inevitable that some class names, or other
types of member names, are going to be the same as some other member of
something somewhere else. Depending on the context, or scope of the
situation, it might be easier to make the distinction.
So, you start a project, and you add a reference to 2 different DLLS in your
project. These are 2 completely different DLLs, but they have some classes
in them with the same name as in the other DLL. In your code, so that you
don't have to write out the full namespace of the assembly in which the
different classes reside, you add the following:
using foo;
using bar;
foobar theFoo = new foobar();
Suddenly, you get a compiler exception: Ambiguous name reference. You see,
the foo assembly has a class named foobar, and so does the bar assembly. How
does the compiler know which one your code is referring to? Well, you want
the foo version, so you change your code:
foo.foobar theFoo = new foobar();
Suddenly, the sun comes out, and everything is fine again. But let's look at
another possibility:
using foo;
foobar theFoo = new foobar();
No exception is thrown. Why? Because you didn't add the "using bar;"
statement. To reference bar.foobar you would have to use the full namespace,
as the compiler would have no context to identify the class. The compiler
has to know at all times the exact address of the member referenced.
sometimes it can infer it from the context:
public class foo
{
public string bar = "foobar";
public string foobar()
{
return bar;
}
}
Of course, it could read:
public string foobar()
{
return this.bar;
}
But as the function exists in the context of the class foo, the compiler can
infer the namespace of the address of the field.
In other words, a namespace is a way of defining a unique ADDRESS of
something in memory. You and I see code in a file. The application, once
compiled, sees addresses in memory. The compiler can infer some of them
during compilation, which involves the assignment of the addresses of code.
But there has to be a mechanism for uniquely idenfying others in your code,
so that the compiler can correctly discern which address belongs to what
token in your code.
Why are namespaces hierarchical? For purposes of easy organization. A
hierarchy is a tree, like a postal address. Consider the following postal
address:
13 Mockingbird Lane, Anytown, USA
The address becoms more specific from right to left. "USA" eliminates all
addresses outside of the U.S. "Anytown" eleminates all address outside the
U.S., and outside "Anytown" IN the U.S. "Mockingbird Lane" further
eliminates any address not on Mockingbird Lane. And 13 uniquely identifies
that house on that street. 13 by itself does nothing. Most streets have an
address of 13. Mockingbird Lane does nothing by itself either. Many cities
and towns have a Mockingbird Lane. And so on. But by successively elminating
branches of the "tree" you narrow it down in short order to a single unique
address. If the Earth is the tree, countries are the immediate branches,
cities are branches off of those, streets are branches off of city branches,
and the numbers are the individual leaves on those branches. a hierarchical
(or tree) structure is the most efficient means of uniquely identifying
anything in any type of organization.
Hope that makes things a bit clearer.
--
HTH,
Kevin Spencer
Microsoft MVP
..Net Developer
A watched clock never boils.
"Bruce Wood" <br*******@canada.com> wrote in message
news:11**********************@z14g2000cwz.googlegr oups.com...
Here's my stab at explaining namespaces. I hope you find it useful.
The runtime pays scant attention to namespaces, as Michael S pointed
out. Every class has a rather long name, such as
System.Collections.ArrayList. That's the real name of the class, not
ArrayList, and in fact you can write all the references to classes
outside your current project that way, without ever writing a single
"using" directive. If you look at the code that the Forms Designer
generates, you'll see that it never defines just Label, for example. It
always generates code that says System.Windows.Forms.Label. (There's a
reason, which I'll mention later. For now, just notice that it's
perfectly valid to do this.)
However, for most of us, that would be horribly tedious: the code would
be longwinded and difficult to read.
So, the "using" directive comes to the rescue. I can "open up" a
namespace by saying,
using System.Collections;
and now when I mention "ArrayList", the compiler knows to look not only
in my own code, but also in all of the things with names starting with
"System.Collections." to see if it can find something called
"ArrayList". This makes the code a lot easier to read. Nonetheless, at
the end of the day all of the class names that the compiler generates
in the IL are all fully qualified: the compiler will write
System.Collections.ArrayList out the back end, no matter what.
This, however, is not the reason why namespaces were created. MUS
explained the motivation: there are people all over the world writing
reusable libraries. I don't want to be required to consult some
enormous, global dictionary of class names that people have already
used and avoid calling my classes by those names in case I want to use
someone else's library. What a disaster if I write my own code and then
later decide to plug in your library, and discover that there are 30
class names (or 300 class names) that I used in my code that you also
used in yours.
.NET and Java solve this problem by allowing each of us to "wrap" our
code in a namespace. Then all that we have to do is make sure that we
don't use the same namespace name. The Java convention was to always
use a URL in reverse. If you own the URL, then you're guaranteed that
nobody else will have the same namespace name. For example, if the
folks at Google were to write some search tools, they could wrap them
in namespace
namespace com.google.SearchTools
{
}
and be assured that nobody else in the world will have class names that
collide with theirs. (Remember that the true name of every class
defined within those curly braces would be "com.google.SearchTools...",
not just the name written in the class declaration.)
This is why the Forms Designer writes all class names as
fully-qualified. For all it knows, you may have defined a class called
Label in your form's namespace, and so if the Designer were to write
just "Label" then it runs the risk of creating an instance of one of
your classes, not of System.Windows.Forms.Label, so it plays it safe
and always uses the fully-qualified name, which is guaranteed to always
work.
So why does the Class View, among other things, present namespaces to
us as though they were hierarchies when in fact they aren't (with the
exception noted by Jon Skeet)? Only because it's convenient for us
think about them that way. It's a nice way to organize code, even if
the compiler, in the end, flattens the whole thing out and generates a
bunch of classes with really long names gathered into assemblies. Like
everything else in computing, it's about making it easier for us
programmers to organize and maintain our solutions. Don't forget that
everything we do gets boiled down to bits of data and machine code in
the end (and the machine doesn't even really make that distinction)...
everything other than binary code is there for our benefit, not the
computer's. Namespaces are just another example of that phenomenon.
One thing I have yet to figure out then is how to know which assembly the
System.Collections.ArrayList class would belong to?
Well, I'm not dab hand with the class browser... I hardly ever use
it... but the way it organizes what it shows to me is as a hierarchy:
projects containing namespaces, which can contain other namespaces,
which in turn contain classes, which contain fields, methods,
properties, etc.
I don't even know how to have the class browser show me the
organization of the Framework namespaces. Anyone?
I rely on the MSDN documentation for the Framework to tell me where a
class lives: the main "about" page for each class shows, near the
bottom, which DLL it lives in.