Confused by namespaces

D

Dylan Parry

Hi,

I've started to get a bit confused by namespaces and hierarchical
organisation in general. What I want to do is something like this:

Namespace MyNamespace
|
|- Class Foo
|
|- Namespace MyNamespace.Foo
| |
| |- Class Example
| |
| |- Class AnotherExample
|
|- Class Bar

In the above, I have a namespace containing all of my work and within
that namespace I have a class called /Foo/ that can be used to create
objects of type /Foo/.

Now what I want is to have a namespace within /MyNamespace/ that is also
called /Foo/. Obviously this conflicts with the class of the same name.

So I suppose my question is really how do I organise the above into
something that is *actually* possible to achieve so that I can have a
class /Foo/ that is hierarchically the parent of classes /Example/ and
/AnotherExample/?

Can you suggest any good reading on C# namespaces in general, and how I
can get my head around them?

TIA,
 
B

Bruce Wood

In C#, as in Java, namespaces have no relation to each other, so you
can't "hierarchically relate" them, and you can't nest them. You can
give them names that give the *impression* of hierarchy, like
MyNamespace and MyNamespace.Foo, but they're not really in a hierarchy:
they just have names that suggest a hierarchy to the reader.

If what you want is to have classes Example and AnotherExample
intimately associated with class Foo, to send the message (to other
programmers) that Example and AnotherExample are meant to be used
together with Foo and in no other context, then you can nest classes
like this:

Namespace MyNamespace
|
|- Class Foo
| |
| |- Class Example
| |
| |- Class AnotherExample
| |
| end class Foo
|
|- Class Bar

then the four (full) class names would be:

MyNamespace.Foo
MyNamespace.Foo.Example
MyNamespace.Foo.AnotherExample
MyNamespace.Bar

Is this the effect you wanted?
 
D

Dylan Parry

Pondering the eternal question of "Hobnobs or Rich Tea?", Bruce Wood
finally proclaimed:

[...]
Is this the effect you wanted?

In the /pseudo/-hierarchical way I was thinking, yes, I think it is.

If I were to do how you suggest, then could I create a new instance of
the /Example/ class without having already created an instance of /Foo/,
or would /Example/ only be able to exist once I have created a /Foo/
object?

If the latter, then how would this work? Would I still use:

MyNamespace.Foo.Example ex = new MyNamespace.Foo.Example();

or would it be more complicated than that?

Please forgive me if I am being an uneducated arse, but I am struggling
to understand the whole namespaces thing, having moved into C# from
languages that don't use namespaces :)
 
B

Bruce Wood

If I were to do how you suggest, then could I create a new instance of the /Example/ class without having already created an instance of /Foo/, or would /Example/ only be able to exist once I have created a /Foo/ object?

In C#, the former. The latter is sort of how Java works.

Namespaces are, generally speaking, simpler than you might imagine.
They're nothing more than a way of grouping identifiers. Or, if you
wish, a shorthand. Notice that in my post I mentioned that the "full
names" of the classes would be:

MyNamespace.Foo
MyNamespace.Foo.Example
MyNamespace.Foo.AnotherExample
MyNamespace.Bar

In order to avoid having to say "MyNamespace." all over the place in
the C# file that defines these classes, you wrap all of the code in a
"namespace" block:

namespace MyNamespace
{
... define Foo, Foo.Example, Foo.AnotherExample, Bar
}

The compiler doesn't let you, but this is equivalent to the (illegal)
syntax that follows, with no enclosing "namespace" block:

public class MyNamespace.Foo
{
public class Example { ... }
public class AnotherExample { ... }
}

public class MyNamespace.Bar
{
}

For things that you're using from other namespaces (other than the one
in which you're defining new types at the moment), there's the "using"
clause:

using System.Windows.Forms;

which in this case really does do nothing other than save you having to
type "System.Windows.Forms.Label" or "System.Windows.Forms.Combobox"
all over the place and lets you type "Label" or "Combobox" instead.

Namespace names with periods in them, that give the impression of
hierarchical organization, are a ruse to help programmers mentally
organize information. From the compiler's point of view,

System.Text

and

System.Text.Encoding

are just two independent namespaces. The fact that the name of one is a
substring of the name of the other means nothing. (This is also true in
Java... with one caveat on which Jon Skeet corrected me that I can't
recall at the moment.)

That's about it... other than the fact that all of this contains one
small lie: the "full" name of a type also includes the name of the
assembly from which it was loaded (including the assembly version). So
a full class name is *really* assembly name, assembly version,
namespace, and simple type name combined. Now, versioning... there's a
topic to make the head spin, but don't confuse that with namespaces,
which although they seem complicated aren't really.

Don't worry about being an uneducated arse. I am as well. :)
 
D

Dylan Parry

Pondering the eternal question of "Hobnobs or Rich Tea?", Bruce Wood
finally proclaimed:
In C#, the former. The latter is sort of how Java works.

Thanks, that's how I was hoping it would work as it seemed the easier of
the solutions to get my head around!
Namespaces are, generally speaking, simpler than you might imagine.
[...]

That was an incredibly useful summary; very easy to understand.
Don't worry about being an uneducated arse. I am as well. :)

Heh, well for somebody with a couple of degrees behind him, I have to
admit that I felt very thick when confronted with namespaces! Although,
my education finished a few years back and I've had enough time to
forget all the important stuff ;)
 
B

Bruce Wood

I'm glad you found that useful.

One more small point about the "using" clause. The compiler doesn't
mind at all if you "use" two namespaces that contain one or more type
names in common. So, if you were to have two types, ANamespace.Foo, and
AnotherNamespace.Foo, and you said this in your program:

using ANamespace;
using AnotherNamespace;

the compiler is quite happy with that. The only thing it requires is
that whenever you mention "Foo" you have to given its full name, so
that the compiler knows which one you're talking about. No shorthand
allowed, but only for that type name:

AnotherNamespace.Foo afoo = new AnotherNamespace.Foo();

If you just say

Foo afoo = new Foo();

the compiler will complain that it doesn't know which "Foo" you mean.

This is *exactly* the same as working in an office with three guys
named Andrew (which I do :) ). I can't go around talking to people
about "Andrew"... I have to use their full names so my listener knows
which one I'm talking about. Everyone here, however, can just talk
about "Bruce" because there's only one of me. :) Same deal.
 
B

Bruce Wood

In C#, the former. The latter is sort of how Java works.
Thanks, that's how I was hoping it would work as it seemed the easier of the solutions to get my head around!

Yes... the difference between the two languages is that in Java,
declaring a class nested inside another (can) give the inner, nested
class access to the outer, enclosing class's instance members
(depending upon how the inner class is declared). In that case, of
course, you can only create an instance of the inner class within an
existing instance of the outer class... or something like that... I've
forgotten the precise details.

In C#, the only advantages to nesting classes are naming and access.
Naming because you can use nesting to indicate relationships between
classes (e.g. ListViewItemCollection is intended to be used with a
ListView). Access because you can declare the inner class so that it is
visible only to the enclosing class, or visible only to the enclosing
class and its child classes. Access, as well, because the inner class
can "see" private members (fields, properties, methods, events) of the
enclosing class, so this is legal:

public class A
{
private static int x;

private class B
{
private int y;

B()
{
y = A.x;
}
}
}

(Notice that "x" is static... otherwise A.B would have to create an
instance of A to get at it.) Other than that, the nested class is just
a boring, ordinary class like any other, just with a compound name.
 
D

Dylan Parry

Pondering the eternal question of "Hobnobs or Rich Tea?", Bruce Wood
finally proclaimed:

<stuff about namespaces>
[...]

Thanks for all that extra info. You've cleared up a lot of loose ends in
my head, so hopefully I will be able to restructure my current project
tomorrow so that it actually makes sense :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top