Presentation is loading. Please wait.

Presentation is loading. Please wait.

第 12 章 命 名 空 间 (时间: 1 次课, 2 学时)

Similar presentations


Presentation on theme: "第 12 章 命 名 空 间 (时间: 1 次课, 2 学时)"— Presentation transcript:

1 http://www.wenyuan.com.cn/webnew/ 第 12 章 命 名 空 间 (时间: 1 次课, 2 学时)

2 http://www.wenyuan.com.cn/webnew/ 第 12 章 命 名 空 间 我们曾在第 2 章中提过命名空间 (namespace) ,而且我们在 所有的示例中都使用了 System 这个命名空间。 System 命 名空间中包含有大量的系统方法和类,.NET 框架就是使用 命名空间来组织和交流程序代码的。本章将正式介绍有关命 名空间的定义、清单、组合体和版本的概念及应用特征。 本章教学目的: 理解命名空间的含义和 C# 应用程序的组织结构 掌握命名空间的定义和有效使用范围 掌握 using 语句的使用方法 了解.NET 框架类库中的命名空间

3 http://www.wenyuan.com.cn/webnew/ 第 12 章 命 名 空 间 12.1 命 名 空 间 12.1 命 名 空 间 12.2 定义命名空间 12.2 定义命名空间 12.3 使用命名空间 12.3 使用命名空间

4 http://www.wenyuan.com.cn/webnew/ 12.1 命 名 空 间 命名空间是用来限定名称的解析和使用范围的,比如,当我 们处在自己的家庭环境下时,可以直呼小名;在工作单位就 必须称呼全名;如到外地出差,则还必须说明本人是某某地 方、某某单位的某某人。这其中,家庭、工作单位和外地就 是不同的命名空间,也就是说,同一个人在不同的环境或场 合 ( 命名空间 ) 下对他的称呼是不同的。 C# 语言使用命名空间来管理和组织代码 ( 管理各种类 ) 。在 C# 中,命名空间是一个逻辑上的类型组织系统,用它来对 程序中的类型进行逻辑上的分组,并使定义在同一个命名空 间中的类可以利用命名空间直接相互调用。

5 http://www.wenyuan.com.cn/webnew/ 12.2 定义命名空间 定义命名空间使用 namespace 关键字,其语句格式为: namespace 命名空间名 { …… // 命名空间的成员 ( 其他命名空间或类的定义 ) } 其中: “ 命名空间名 ” 是 C# 合法的标识符。也可以是用点运算符来构成命名空间的完全限定名。 在默认情况下,命名空间具有 public 访问属性。不允许在定义命名空间时使用任何访问修 饰符。 命名空间的成员可以是另一个命名空间或类型 ( 类、结构、接口、枚举和代理 ) 的定义。如 果类型是命名空间的成员,则该类型只能具有 public 或 internal 访问修饰符,其中 internal 是默认的访问权限。

6 http://www.wenyuan.com.cn/webnew/ 12.2 定义命名空间 【例 12.1 】定义一个计数器命名空间。 namespace Counter { class DownCount // 倒数计数器 { int v; public DownCount(int n) {v=n; } // 构造函数 public void reset(int n) {v=n;} // 置初值 public int count() // 倒数计数方法 { if (v>0) return v--; else return 0; }

7 http://www.wenyuan.com.cn/webnew/ 12.3 使用命名空间  12.3.1 命名空间的完全限定名 12.3.1 命名空间的完全限定名  12.3.2 C# 应用程序的组织结构 12.3.2 C# 应用程序的组织结构  12.3.3 using 语句 12.3.3 using 语句

8 http://www.wenyuan.com.cn/webnew/ 12.3 使用命名空间

9 http://www.wenyuan.com.cn/webnew/ 12.3.1 命名空间的完全限定名 程序中的命名空间就如同文件和文件夹。文件夹包含许多文件和其他文 件夹,同样,命名空间也可以包含其他命名空间。由于命名空间是用来 组织代码的,所以必须层次化定义它们。方法是:在层次体系的顶层定 义通用命名空间,然后在其中定义具体的命名空间。这种层次化的命名 空间称为嵌套命名空间,另外命名空间和类也可以构成程序的嵌套。我 们往往用命名空间的完全限定名来表示这种层次的命名空间,例如: namespace N1 { namespace N2 { class ClassA{…… } class ClassB{…… } }

10 http://www.wenyuan.com.cn/webnew/ 12.3.1 命名空间的完全限定名 上述语句等价于: namespace N1.N2 // 完全限定名 N1.N2 { class ClassA{…… } class ClassB{…… } } 也等价于: namespace N1.N2 { class ClassA{…… } } namespace N1.N2 { class ClassB{…… } }

11 http://www.wenyuan.com.cn/webnew/ 12.3.1 命名空间的完全限定名 在相同的命名空间中不能存在名称相同的类型或命名空间;如果类型或命名空间位于不同的命名空间中,它们可以具有相同的名字,例如: namespace N1.N2 { class ClassA{…… } class ClassB{…… } } namespace N1.N3 { class ClassA{…… } class ClassB{…… } } 以下代码段中有嵌套的类和命名空间,可以用命名空间和类的完全限定名来表示程序的嵌套关系。 namespace N1 //N1 { class C1 //N1.C1 { class C2 {…… } //N1.C1.C2 } namespace N2 //N1.N2 { class C2 { …… } //N1.N2.C2 } 命名空间 N1 是全局命名空间的一个成员,它的完全限定名就是 N1 。命名空间 N2 是 N1 的成员,它的完全限定名是 N1.N2 。类 C1 是 N1 的一个成 员,它的完全限定名是 N1.C1 。类 C2 在程序中使用了两次,第一次的完全限定名是 N1.C1.C2 ,第二次的完全限定名是 N1.N2.C2 。

12 http://www.wenyuan.com.cn/webnew/ 12.3.2 C# 应用程序的组织结构 C# 程序是由一个或多个文件组成,每个文件可以包含一个或多个命名空间,而每个命名 空间又可以包含各种数据类型,如类、结构、接口、枚举和代理,甚至还可包含其他命名 空间。 C# 程序的基本框架如下: // 一个 C# 程序的基本框架 using System; // 引入命名空间 namespace MyNamespace1 // 自定义命名空间 { class MyClass1 {……} // 定义类 struct MyStruct {……} // 定义结构 Interface MyInterface{……} // 定义接口 delegate int MyDelegate() ; // 定义代理 enum MyEnum{ ……} // 定义枚举 namespace MyNamespace2 {…… } // 嵌套的命名空间 }

13 http://www.wenyuan.com.cn/webnew/ 12.3.2 C# 应用程序的组织结构 由此可见, C# 的应用程序是用命名空间来组织的:所有的 C# 程序都具有一个全 局命名空间 (global namespace) ,我们在程序中声明的所有顶层 ( 不属于任何 其他的命名空间 ) 命名空间和类型都是这个全局命名空间的成员,因此在程序中 对各种数据类型的定义就构成了命名空间的层次结构。在 C# 中,有以下 4 种不 同的命名空间。 全局命名空间 是指在所有源代码文件顶层声明的命名空间或类型。每个 C# 程 序只有一个全局命名空间。 命名空间 一个命名空间可在多个源代码文件中多次声明,但是,只要它们的完 全限定名相同,就认定是同一个命名空间。 类型命名空间 类型 ( 类、结构或接口 ) 定义本身就声明了一个类型命名空间。类 型的所有成员都属于这个命名空间。但是,基类和基接口不属于类型命名空间, 所以在派生类或接口中可以声明与基类或基接口同名的命名空间成员。 语句块命名空间 由花括号 “{ }” 括起来的语句块或 switch 语句块等定义的一个 命名空间。所有位于其中的本地变量定义或嵌套语句块都属于这个命名空间。

14 http://www.wenyuan.com.cn/webnew/ 12.3.3 using 语句 C# 中的 using 语句为我们使用命名空间及其中定义的类型提供了方便的 途径,我们可以将某个类封装在某个命名空间中,然后编译成类库 ( 动态 链接库 ) ,在其他应用程序中使用 using 语句就可以调用它了。一个 using 语句的有效范围是在直接包含它的编译单元或命名空间定义体的 内部。 使用命名空间的一般语句格式为: using [ 别名 = ] 命名空间完全限定名; using 语句为我们提供了两种使用命名空间的方式。

15 http://www.wenyuan.com.cn/webnew/ 12.3.3 using 语句 1. 命名空间 using 语句 格式: using 命名空间完全限定名; 作用:引入一个命名空间成员。 例如: using System; 我们在编写程序时,最好将这个 using System 语句放在程序代码的开始位置,这样当我 们使用命名空间 System 中的各种类成员时,就不用再包含这个命名空间的名称 System 。 比如,我们在程序中可直接使用 Console.WrietLine ,而不用包含 System 名称,即可避 免重复写出各个类成员的完全限定名。再如: namespace N1.N2 { class ClassA{…… } } namespace N3 { using N1.N2; // 导入命名空间 N1.N2 class ClassB: ClassA { ……} // 直接用类名来引用 ClassA }

16 http://www.wenyuan.com.cn/webnew/ 12.3.3 using 语句 以上命名空间 N3 中导入了命名空间 N1.N2 ,所以后者的成员 ClassA 对 N3 是可用的,这样 N3 的成员 ClassB 就可以直接使用 N1.N2 的成员 ClassA 作为其基类,而无需在程序中重复写出 ClassA 的完全限定 名 N1.N2.ClassA 。 using 语句只能导入命名空间中的类型成员,不能导入命名空间中的嵌套命名空间。请看以下代码: namespace N1.N2 { class ClassA{…… } } namespace N3 { using N1; // 导入命名空间 N1 class ClassB: N2.ClassA {…… } // 错误!命名空间 N2 未被导入 } 这里 using 语句只导入了命名空间 N1 中包含的类,但并没有导入 N1 中的嵌套命名空间 N2 ,所以对 ClassB 来说, N2 是未知的。 使用 using 语句导入的命名空间可以与包含此 using 语句的命名空间有相同名称的类成员,由于它们属 于不同的命名空间,所以导入的类型将被新定义的类所隐藏,请看以下代码:

17 http://www.wenyuan.com.cn/webnew/ 12.3.3 using 语句 namespace N1.N2 { class ClassA{…… } class ClassB{ ……} } namespace N3 { using N1.N2; // 导入命名空间 N1.N2 // 以下新定义的类将隐藏导入的命名空间 N1.N2 中的同名类 N1.N2.ClassA class ClassA {…… } } 如果使用 using 语句导入的多个命名空间中包含了同名的类,则不能直接通过类型名来使用这些类,由于这具有二义性,所以要使用类型的完全限定名或使用它 们的别名来引用指定的命名空间中的类。例如以下代码: namespace N1 { class ClassA{…… } } namespace N2 { class ClassA {…… } } namespace N3 { using N1; // 引入 N1 using N2; // 引入 N2 class ClassB: ClassA{….. } // 错误!类 ClassA 存在二义性 class ClassC: N2.ClassA{…… } // 正确!通过完全限定名来访问指定命名空间中的 同名类 }

18 http://www.wenyuan.com.cn/webnew/ 12.3.3 using 语句 2. 别名 using 语句 C# 支持别名的使用。别名 using 语句可以为一个命名空间或类定义一个别名,然后就可以 在程序中使用这个别名来引用相应的命名空间或类中的成员。别名 using 语句格式如下: using 别名 = 命名空间或类的完全限定名; 该语句的作用是:定义了一个命名空间或类的别名。例如: namespace N1.N2 { class ClassA {…… } } namespace N3 { using A=N1.N2.ClassA; // 定义 N1.N2.ClassA 别名为 A class ClassB: A {…… } // 程序中直接使用别名 A } 上述代码中,命名空间 N3 中定义了一个别名 A ,并且成员 ClassB 使用了该别名作为其基类, 相当于类 ClassB 是从类 N1.N2.ClasA 派生的。

19 http://www.wenyuan.com.cn/webnew/ 12.3.3 using 语句 别名 using 语句中定义的别名在包含该别名语句的编译单元或命名空间中的定义必须是惟一的。请看以下代码: namespace N1.N2 { class ClassA {…… } } namespace N3 { using TypeA=N1.N2.ClassA; // 错误! N3 中已包含成员 TypeA ,别名就不能再用 TypeA class TypeA {…… } } 在同一个编译单元或命名空间内部,不能定义相同的别名。另外,要使用的别名只在定义它的编译单元或命名空间定义体内有效。请看以下代码: namespace N1.N2 { class ClassA { } } namespace N3 { using M=N1.N2; // 别名 M } namespace N4 { class ClassB : M.ClassA{ } // 错误!别名 M 在 N3 中, N4 未知 }

20 http://www.wenyuan.com.cn/webnew/ 12.3.3 using 语句 以上错误的原因是别名 M 只在包含它的命名空间定义体内有效,而在命名空间 N4 的定义 中, M 是未知的。但是可以用别名 using 语句专门构成一个编译单元,再次编译单元内的 二次命名空间中,以上的 M 别名就是有效的了。代码如下: namespace N1.N2 { class ClassA {……. } } using M=N1.N2; // 用别名 using 语句构成一个编译单元 namespace N3 { class ClassB: M.ClassA{……. } // 正确! M 是有效的 } namespace N3 { class ClassC : M.ClassA{……. } // 正确! M 是有效的 }

21 http://www.wenyuan.com.cn/webnew/ 12.3.3 using 语句 在同一个编译单元或命名空间定义体内,各别名 using 语句的作用是相 互独立的,且与别名 using 语句的顺序无关,有以下代码: namespace N1.N2 { class ClassA {…… } } namespace N3 { using M1=N1; // 正确 using M2=N1.N2; // 正确 using M3=M1.N2; // 错误! M1 是未知的 }

22 http://www.wenyuan.com.cn/webnew/ 12.3.3 using 语句 由于在同一个编译单元或命名空间定义体内各别名 using 语句互不影响,所以上述代码中最后一个 using 语句是错误的。 使用别名来访问一个命名空间或类与直接使用完全限定名访问的效果是一样的。例如: namespace N1.N2 { class ClassA {…… } } namespace N3 { using M1=N1; using M2=N1.N2; class ClassB { N1.N2.ClassA x; // 通过完全限定名 N1.N2.ClassA 引用类 ClassA M1.N2.ClassA y; // 通过别名引用类 ClassA ,相当于 N1.N2.ClassA M2.ClassA z; // 通过别名引用类 ClassA , N1.N2.ClassA }

23 http://www.wenyuan.com.cn/webnew/ 12.3.3 using 语句 【例 12.2 】定义两个 Counter 命名空间,一个包含类 DownCount( 倒数计数器 ) ,另一个包含类 UpCount( 正数计数器 ) 。使用 using 语句将这两个 Counter 命名空间构成一个命名空间体 ( 或编译单元 ) 。 using System; using Counter; // 使用 Counter 命名空间构成一个命名空间体 namespace Counter // 一个 Counter 命名空间 { class DownCount // 倒数计数器 { int v; public DownCount(int n) {v=n; } // 构造函数 public void reset(int n){ v=n; } // 计数器置初始值 public int count() // 倒数计数方法 { if (v>0) return v--; else return 0; }

24 http://www.wenyuan.com.cn/webnew/ 12.3.3 using 语句 namespace Counter // 另一个 Counter 命名空间 { class UpCount // 正数计数器 { int v; int goal; public UpCount(int n) // 构造函数 { goal=n; v=0; } public void reset(int n) { goal=n; v=0; } public int Goal { get{return goal; }} // 类的属性成员 public int count() { if (v<goal) return v++; else return goal; } class App {

25 http://www.wenyuan.com.cn/webnew/ 12.3.3 using 语句 public static void Main() { DownCount dc=new DownCount (10); // 倒数计数器对象 UpCount uc=new UpCount (10); // 正数计数器对象 int i; do // 倒数 { i=dc.count(); Console.Write(i+" , "); }while(i>0); Console.WriteLine(); do // 正数 { i=uc.count(); Console.Write(i+" , "); }while((i<uc.Goal); Console.WriteLine); } 程序运行结果: 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 , 0 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 本例通过使用 using 语句包括了 Counter 命名空间的全部内容,所以类 DownCount 和类 UpCount 都可以直接引用,而不需要使用完全限定名。

26 http://www.wenyuan.com.cn/webnew/ Q & A? Thanks!


Download ppt "第 12 章 命 名 空 间 (时间: 1 次课, 2 学时)"

Similar presentations


Ads by Google