Reputation: 1819
Assuming namespace A2
is nested within namespace A1
, then A2
is a member of enclosing A1
. But members of A2
( thus types declared within A2
) are not members of A1
.
a) What exactly is meant by members of A2
not being members of A1
? In other words, what would be different if they were also members of A1
? Perhaps that inside A1
we wouldn’t have to use fully qualified name for types in defined in A2
?
b) What exactly is it meant by namespace A2
being a member of A1
?
BTW - I do understand namespaces, I'm just confused by the terminology used by my book ( namely, A2 being a member of A1 etc )
thanx
EDIT
1) So essentially A2
being a member of A1
is the reason why inside A1
we don't have to specify A1. prefix
when referencing types declared in A2
:
namespace A1
{
class Program
{
static void Main(string[] args)
{
A2.classA2 a2= A2.classA2(); //here we don't need to include A1.
prefix
}
}
namespace A2
{
class classA2 { }
}
}
2) The following is defined within assembly asmLibrary.dll
namespace A
{
public class A1{}
namespace B
{
public class B1{}
}
}
The following application App1
also has a reference to assembly asmLibrary.dll
:
namespace A
{
class Program
{
static void Main(string[] args)
{
B.B1 instanceB1 = new B.B1();
}
}
}
The following application App2
has a reference to assembly asmLibrary.dll
:
using A;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
A.B.B1 bInstance = new A.B.B1();
A1 a1 = new A1();
}
}
}
a) When we tried to declare in App2
an instance of A.B.B1
, we needed to specify fully qualified name of the type. But with App1
we were allowed to specify the type via B.B1
. Thus why were we allowed to ommit the A.
prefix inside App1
, but not inside App2
( App2
has a using A;
directive, so its behaviour should be identical to that of App1
)?
b) Also, if namespace B
is a member of namespace A
, shouldn't then App2
allow us to declare a type A.B.B1
using B.B1 instanceB1 = new B.B1();
syntax?!
Upvotes: 3
Views: 467
Reputation: 273179
Consider the following
namespace A1
{
namespace A2 // A1.A2
{
class C2 // full name: A1.A2.C2
{
private A1.C1 c1b; // full name
private C1 c1b; // shortest form. A1 is in scope here
}
}
class C1 // full name: A1.C1
{
private A1.A2.C2 c2a; // full name
private A2.C2 c2b; // shortest form. We can omit the A1 prefix but not A2
}
}
Answers
a) the class C2 is not a (direct) member of A1, so outside of the A2 namespace we have to declare
it as A2.C2 c2b;
b) The members of A1 are in scope inside A2, see the declaration of C1 c1b;
Re the Edit:
Your example shows the different effects of using a; ...
and namespace A { ... }
.
The using statements 'imports the types from A (§ 16.3.2)' while in App2 the code is inside the namespace.
The term 'member' can be a bit confusing here.
Upvotes: 3
Reputation: 837946
The meaning of member is covered in the C# specification, section 3.4:
Members
Namespaces and types have members. The members of an entity are generally available through the use of a qualified name that starts with a reference to the entity, followed by a “.” token, followed by the name of the member.
Members of a type are either declared in the type declaration or inherited from the base class of the type. [...]
The definition of "namespace members" is given section 3.4.1:
Namespace members
[...]
Namespaces and types declared within a namespace are members of that namespace.
It means that just because A1.A2.Foo
works, it doesn't imply that A1.Foo
also works.
Upvotes: 1
Reputation: 15325
As far as I understand, IL has no concept of namespaces. The compiler appends namespace names and type names to compose longer full names; for example, class Customer
in namespace MyCompany.MyProduct
will be rendered as something like MyCompany$MyProduct$Customer
when compiled into IL. To the IL virtual machine, that is a type name; the fact that it contains $
signs is irrelevant.
From that fact you can derive your own conclusions. :-)
Upvotes: 1
Reputation: 24988
Members of A2 are members of A2 - "the buck stops there". If the A1 contained definitions of the members of A2 then nothing changes - whichever way you'll need to reference these members as A1.member and members of A2 as A1.A2.member - unless you have using
statements in which case you'll need to tread carefully if you want to avoid compiler errors.
Upvotes: 1