[摘自c#Bible]c#中namespace的使用(命名空间)

The C# classes that you design will be used by code that you write and possibly by code that

other people write. Your C# classes may be used by a VB.NET application or from within an

ASP.NET page. Moreover, your classes may very well be used alongside other classes

designed by other .NET developers.

Code written in a .NET language references classes by their names, and all of these classes

used together suggests an obvious dilemma: What happens if a developer wants to use two

classes that have the same name?

Suppose you write a C# class that reads records from a database and you name the class

Recordset. Code that wants to use your class may create objects as follows:

Recordset MyRecordset = new Recordset();

Now suppose that you package your classes into a .NET assembly and distribute your

assembly for use by other applications. Furthermore, suppose that someone obtains your

assembly and integrates it into his or her application. What happens if that same application

also makes use of another assembly written by someone else, which also contains a class

called Recordset? When the application code creates a new Recordset object, which class is

used to create the object: yours or the class in the other assembly?

This problem can be solved through the C# concept of name-spaces. Namespaces organize

classes under a named group, and the namespace name can be used to help distinguish

between two classes with the same name. Your C# code should use namespaces to help

further identify your classes under a common grouping, especially if you are planning to build

an assembly for use by other developers. Namespaces may even come in handy in C#

applications that you build, because your C# applications may use an external assembly that

uses class names which mirror yours.

Declaring a Namespace

You declare a namespace with the C# namespace keyword. A namespace identifier and curly

brackets follow the namespace keyword. Classes to be included in the namespace must be

declared within the namespace's curly brackets, as the shown in the following code:

namespace MyClasses

{

class MyFirstClass

{

}

}

 

This piece of code declares a class called MyFirstClass in a namespace called MyClasses.

Another developer may also write a class called MyFirstClass, but as long as the other

developer uses a different namespace name, the C# compiler finds the correct class to be used

for a particular statement.

You can declare a namespace within a namespace, if you wish. Simply enclose another

namespace declaration from within the first declaration:

namespace MyClasses

{

namespace MyInnerNamespace

{

class MyFirstClass

{

}

}

}

Tip It's generally a good idea to nest namespaces when you plan to offer more than one

distinct product in the form of classes. For example, Widget Corporation offers a

compression product and some terminal emulation routines. These namespaces would

then become Widget.Compression and Widget.Emulation, which group the products by

company but also keep them separated under the Widget namespace.

If you don't want to nest namespaces in this manner, you can achieve the same effect by

declaring both namespace declarations on the same statement and separating them with a

period, as follows:

namespace MyClasses.MyInnerNamespace

{

class MyFirstClass

{

}

}

The following types of declarations can appear in a namespace:

Classes

Structures

Interfaces (see Chapter 13 for more information)

Enumerations (see Chapter 14 for more information)

Delegates (see Chapter 15 for more information)

Any type declaration not in this list results in compiler errors when you attempt to build your

application.

Declaring a Namespace in Multiple Source Files

The C# compiler enables you to use the same namespace name in multiple source files. It then

builds a binary file that combines all the classes into the same namespace.

Suppose, for example, that you want to build an assembly whose classes reside in a

namespace called MyAssembly. You want to write two classes for inclusion in that assembly

and you want to define the classes in separate files. You can simply re-use the namespace

name in both source files. The first source file can contain the declaration of the first class, as

follows:

namespace MyAssembly

{

class MyFirstClass

{

}

}

The second source file can contain the declaration of the second class and can use the same

namespace name:

namespace MyAssembly

{

class MySecondClass

{

}

}

When the two source files are built into a single assembly, the C# compiler builds an

assembly with a single namespace, MyAssembly, with two classes in the namespace.

This provides a benefit to you, the developer, should you want to separate certain

functionality into separate files or simply want to keep the length of each source file to a

minimum.

Using Classes in a Namespace

If you want to refer to a class in a specific namespace, you prefix the class name with the

name of its namespace:

MyClasses.MyFirstClass MyObject = new MyClasses.MyFirstClass();

Using this syntax helps you distinguish between classes in different code bases with the same

name. The C# compiler now has enough information to find the right class, because it also

knows what namespace to interrogate in order to find the class you are looking for.

If you are working with classes declared in nested namespaces, all namespace names must

appear when you refer to the class:

Namespace1.Namespace2.MyClass MyObject = new

Namespace1.Namespace2.MyClass();

Listing 12-1 illustrates the namespace concept.

Listing 12-1: Classes in Different Namespaces

namespace Namespace1

{

class TestClass

{

public TestClass()

{

System.Console.WriteLine("Hello from Namespace1.TestClass!");

}

}

}

namespace Namespace2

{

class TestClass

{

public TestClass()

{

System.Console.WriteLine("Hello from

Namespace2.TestClass!");

}

}

}

class MainClass

{

public static void Main()

{

Namespace1.TestClass Object1 = new Namespace1.TestClass();

Namespace2.TestClass Object2 = new Namespace2.TestClass();

}

}

The code in Listing 12-1 declares two classes called TestClass. The two class declarations are

in different namespaces, and the constructor for each class prints a message to the console.

The messages differ slightly so that you are able to tell which message came from which

class.

The Main() method in Listing 12-1 creates two objects: one of type Namespace1. TestClass

and one of type Namespace.TestClass. Because the constructors for the classes write

messages out to the console, running the code in Listing 12-1 results in the output shown in

Figure 12-1.

Figure 12-1: Referencing classes within namespaces

Note that the MainClass class in Listing 12-1 is not enclosed in a namespace declaration. This

is legal in C#. You do not have to enclose classes in namespace declarations. However,

classes that are not enclosed in namespaces cannot use the same name in another class defines

without a namespace.

If you need to use a class that is declared in a namespace, you must use its name- space name

when you use the class name. If you forget to do this, you get an error message from the C#

compiler. Suppose, for example, that the Main() method in Listing 12-1 tries to create an

object of class TestClass:

TestClass Object1 = new TestClass ();

The C# compiler cannot find a class called TestClass defined outside of a name- space, and it

issues the following error:

error CS0234: The type or namespace name 'TestClass' does not

exist in the class or namespace 'MainClass'

If you review the examples from previous chapters, you'll find that you've been using this

syntax all along in your calls to WriteLine(), as shown in the following example:

System.Console.WriteLine("Hello from C#!");

The WriteLine() method is in a class called Console, and the Console class is defined in a

.NET namespace called System.

Namespace Assistance with the using Keyword

You can use the C# keyword using in a variety of ways to make working with namespaces

easier, and save yourself a great deal of typing. At first sight, the using keyword resembles the

typical C/C++ directive #include. Don't let it fool you; the benefits are much more

empowering. The following sections describe some of these benefits.

Aliasing class names with the using keyword

Writing out fully qualified class names that include namespace identifiers can get a bit

tedious, especially if the names are long. You can use the using keyword to provide an aliased

name for the fully qualified class identifier, and you can use the alias name instead of the fully

qualified class identifier once the alias is established.

You can alias a name with a statement having the following structure:

The using keyword

The alias name

An equals sign

The fully qualified class name with the namespace identifier

A statement terminating semicolon

Listing 12-2 adds to Listing 12-1 by aliasing the class names to shorter equivalents. The

shorter names are then used by the Main() method to work with objects of the classes.

Listing 12-2: Aliasing Class Names

using Class1 = Namespace1.TestClass;

using Class2 = Namespace2.TestClass;

namespace Namespace1

{

class TestClass

{

public TestClass()

{

System.Console.WriteLine("Hello from

Namespace1.TestClass!");

}

}

}

namespace Namespace2

{

class TestClass

{

public TestClass()

{

System.Console.WriteLine("Hello from

Namespace2.TestClass!");

}

}

}

class MainClass

{

public static void Main()

{

Class1 Object1 = new Class1();

Class2 Object2 = new Class2();

}

}

As with the previous example, Listing 12-2 outputs the same messages you have previously

seen. You can see these results in Figure 12-2.

Figure 12-2: Aliasing class names

The using statements must appear in the source code before the namespaces themselves are

declared. If the using statements appear after namespace declarations, you receive the

following error message from the C# compiler:

error CS1529: A using clause must precede all other namespace elements

In Chapter 7, you see that the C# keywords defining variable types are actually structures

defined by the .NET Framework. Take another look at Table 7-1 and notice the following:

The value type structures reside in the .NET System namespace.

The using keyword is used to alias the .NET structure names to the equivalent C#

keywords. You may imagine Table 7-1 being implemented within the .NET

Framework using C# statements such as the following:

using sbyte = System.SByte;

using byte = System.Byte;

using short = System.Int16;

// ... more declarations ...

You can alias namespace names as well as classes, as shown in Listing 12-3.

Listing 12-3: Aliasing Namespace Names

using N1 = Namespace1;

using N2 = Namespace2;

namespace Namespace1

{

class TestClass

{

public TestClass()

{

System.Console.WriteLine("Hello from

Namespace1.TestClass!");

}

}

}

namespace Namespace2

{

class TestClass

{

public TestClass()

{

System.Console.WriteLine("Hello from

Namespace2.TestClass!");

}

}

}

class MainClass

{

public static void Main()

{

N1.TestClass Object1 = new N1.TestClass();

N2.TestClass Object2 = new N2.TestClass();

}

}

Declaring namespace directives with the using keyword

If you use a class declared in a namespace, you must prefix the class name with the

namespace name, even if you aren't working with any other namespaces that may have a class

with the same name. This is why the examples used until now have always called WriteLine()

with the System namespace qualifier:

System.Console.WriteLine("Hello from C#!");

By default, forgetting to use the namespace name causes the C# compiler to issue an error:

error CS0234: The type or namespace name 'Console' does not

exist in the class or namespace 'Namespace1'

Prefixing every class name with namespace names like System gets tedious, especially if you

need to do it many times. Fortunately, you can use the using keyword to help reduce your

coding time.

Using the using keyword with a namespace name tells the C# compiler that you want to refer

to classes in the named namespace without prefixing the class names with the namespace

name. For example, take a look at the following statement:

using System;

This is called a namespace directive. Namespace directives tell the C# compiler that the code

will be using classes from the namespace and that the classes won't be prefixed with the

namespace name. The C# compiler does the work of finding the definition of each class in

one of the namespaces referenced in a namespace directive.

Listing 12-4 is a modification of Listing 12-2; it includes a using statement that references the

.NET System namespace.

Listing 12-4: Using a Namespace Directive

using System;

using Class1 = Namespace1.TestClass;

using Class2 = Namespace2.TestClass;

namespace Namespace1

{

class TestClass

{

public TestClass()

{

Console.WriteLine("Hello from

Namespace1.TestClass!");

}

}

}

namespace Namespace2

{

class TestClass

{

public TestClass()

{

Console.WriteLine("Hello from

Namespace2.TestClass!");

}

}

}

class MainClass

{

public static void Main()

{

Class1 Object1 = new Class1();

Class2 Object2 = new Class2();

}

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值