以文本方式查看主题 - 中文XML论坛 - 专业的XML技术讨论区 (http://bbs.xml.org.cn/index.asp) -- 『 Dot NET,C#,ASP,VB 』 (http://bbs.xml.org.cn/list.asp?boardid=43) ---- 微软 .NET平台系列文章之一 (http://bbs.xml.org.cn/dispbbs.asp?boardid=43&rootid=&id=76558) |
-- 作者:卷积内核 -- 发布时间:8/31/2009 3:29:00 PM -- 微软 .NET平台系列文章之一 一年多来,我将注意力一直放在微软的.NET CLR(公共语言运行时:Common Language Runtime)平台。在我看来,今后大多数新的开发都将面向这个平台,因为它使应用程序的开发变得更容易、更简单。同时,我还期望现有的应用开发能迅速移到.NET平台上来。 为了帮助开发人员掌握这个新的平台,本文以及以后的系列文章将专门针对.NET讨论各种编程问题。我将假设你已经熟悉面向对象的编程概念。每一篇文章的内容都聚焦在非选定的特定公共语言运行时编程主题上。所有.NET开发人员必须知道这些主题。 当展示代码例子时,我必须在支持.NET CLR 的多种语言中选择一种。我决定使用C#。它是微软设计的一种新语言。 我的目的是介绍不同的编程主题并就如何实现它们为你提供一些想法。所以,我不想完整的描述每一个主题以及所有与之相关的细微差别。有关主题完整详细的介绍请参考公共语言运行时或者语言文档。 真正的面向对象设计 System.Object class Jeff { 和 class Jeff : System.Object { 因为所有对象都是从System.Object派生出来的,从而可以保证每一个对象具有最小的功能集。[URL=http://www.vckbase.com/vckbase/vckbase9/code/dotNet1000fig.htm#fig1]表一[/URL]是System.Object中的公共方法。 new操作符根据指定的类型需要从堆中分配字节数来创建对象。它初始化对象的开销成员。每一个对象都会有一些公共语言运行时用来管理对象的附加字节,如对象的许表指针以及对同步快的引用。 数据类型的强制转换 System.Object o = new Jeff("ConstructorParam1"); 先前的代码编译通过并正确执行是因为有一个隐含的强制类型转换。new操作符返回Jeff的一个引用类型,但o是一个System.Object的引用类型。因为所有的类型(包括Jeff类型)都能被强制转换为System.Object,隐含的强制类型转换是成功的。但是,如果执行下面的代码,就会有编译器错误,因为编译器不提供基类型到派生类型的强制类型转换。 Jeff j = o; 为了能通过编译,必须插入如下的显式强制类型转换: System.Object o = new System.Object(); 第一行创建了一个System.Object类型对象。第二行代码试图将System.Object引用类型转换为Jeff引用类型。两行代码都能编译通过。但是在执行的时候,第二行代码产生一个InvalidCastException异常,如果捕获不到这个异常,将强制应用程序终止。 当第二行代码执行时,公共语言运行时查证o所指的对象就是Jeff类型对象(或任何Jeff派生类型)。如果是,则公共语言运行时允许强制类型转换。否则,如果o所指的对象与Jeff类型无关,或是一个Jeff的基类,则公共语言运行时会预防这种不安全的强制类型转换并产生InvalidCastException异常。 C# 使用as操作符提供另一种方法来实现强制类型转换: Jeff j = new Jeff(); // 创建一个新的Jeff 对象 as操作符试图强制转换一个对象为指定的类型。但与通常的强制转换不一样,如果对象的类型强制转换不成功,结果会是null,as操作符决不会掷出异常。当引用有毛病的强制类型转换发生时,将产生NullReferenceException异常。下列代码示范了这种情况。 System.Object o = new System.Object(); //创建一个新的Object 对象 j.ToString(); // 访问j时产生一个NullReferenceException 异常 除了as操作符以外,C#还提供一个is操作符。它检查是否一个对象实例与给定的类型兼容并判断结果是True或是False。Is操作符不会产生异常。 System.Object o = new System.Object(); 注意,如果对象引用是null,is操作符总是返回False,因为得不到对象来检查其类型。 class B { class D : B { 现在,参见[URL=http://www.vckbase.com/vckbase/vckbase9/code/dotNet1000fig.htm#fig2]图二[/URL]看看哪一行代码通过编译并执行成功(ES),哪一行代码导致编译器错误(CE),哪一行代码导致公共语言运行时错误(RE)。 |
-- 作者:卷积内核 -- 发布时间:8/31/2009 3:30:00 PM -- 集合与名字空间 类型集可以被分组成集合(一个或多个文件集)并且被展开。在一个集合中可以只存在单独的名字空间。对应用程序开发人员来说,名字空间就像有关联的类型的逻辑分组。例如,基本类库集合包含许多名字空间。System名字空间包括Object基类型、Byte、Int32、Exception、Math和Delegate之类的核心低级类型,而System.Collections名字空间包括的类型如AarryList、BitAarry、Queue和Stack。 对于编译器来说,名字空间只不过是名字较长的的类型名,以及其唯一性是用句点分隔某些符号名来保证的。对于编译器而言,System名字空间中的Object类型只不过是用一个叫做System.Object的类型来表示。同样,System.Collections名字空间中的Queue类型简单地用标示符System.Collections.Queue来表示。 using System; 当我在代码中引用一个类型时,编译器需要保证这个类型被定义过并且我的代码要以正确的方式访问这个类型。如果编译器不能找到指定的类型,它试图将“System.”添加到类型名并检查产生的类型名字是否与现存的类型名匹配。前面的代码行允许我在代码中使用Object,并且编译器将自动将名字展开为System.Object。我肯定你能轻松想象这样省去了多少键盘输入。 using Microsoft; class MyApp { 为了排除这种不明确的引用,你必须显式地告诉编译器,你想创建哪一个FooBar。 using Microsoft; class MyApp { 另一种语句形式是允许你为单独类型创建别名,如果你只使用名字空间中的几种类型并且不想用所有的名字空间类型污染整个名字空间的话,这种方法很方便。下列代码示范了另一种解决类型不明确问题的方法。 // 定义RichterFooBar 为Richter.FooBar的别名 class MyApp { 这种方法对于消除类型歧义有用,但不尽人意的地方仍然存在。假设澳大利亚的飞镖(Boomerang)公司(简称ABC)和阿拉斯加的船舶(Boat)公司(也简称ABC)两家公司各自创建了一个类型。可能两家公司都创建了叫做ABC的名字空间,在名字空间中包含一个叫做BuyProduct的类型。任何试图开发需购买飞镖和船舶应用程序的人将会陷入麻烦,除非编程语言提供编程方法来区分两家公司的集合-而不仅仅是两家公司的名字空间。 namespace CompanyName { // CompanyName namespace X { // CompanyName.X 注意名字空间是隐含的公共类型(public)。不能通过任何访问修饰符改变这一点。但可以在内部的名字空间中定义类型(不能在集合外面使用)或者在公共的名字空间中定义类型(能被任何集合访问)。名字空间只表示逻辑上的限制策略,可访问性和包装是通过将名字空间放入一个集合来完成的。 |
W 3 C h i n a ( since 2003 ) 旗 下 站 点 苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》 |
46.875ms |