知识大全 微软 .NET 在新的平台上编程

Posted 类型

篇首语:情况是在不断的变化,要使自己的思想适应新的情况,就得学习。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 微软 .NET 在新的平台上编程相关的知识,希望对你有一定的参考价值。

微软 .NET 在新的平台上编程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  本文以及以后的系列文章将专门针对 NET讨论各种编程问题 我将假设你已经熟悉面向对象的编程概念 每一篇文章的内容都聚焦在非选定的特定公共语言运行时编程主题上 所有 NET开发人员必须知道这些主题

  当展示代码例子时 我必须在支持 NET CLR 的多种语言中选择一种 我决定使用C# 它是微软设计的一种新语言

  真正的面向对象设计

  对于使用Win SDK的编程人员来说 对大多数操作系统特性的访问时通过一组从动态链接库输出的独立函数实现的 这些独立的函数从诸如C这样的非面向对象语言中非常容易调用 但对于一个新的开发人员来说 要面对上千个表面上看来毫无关系的独立的函数是相当让人畏惧的 更为困难的是许多函数名是以单词 Get 开始的(如GetCurrentProcess和GetStockObject) 此外 Win API已经历数年并且微软添加了新的函数 这些新函数依旧的函数相比 有相似的语义 但提供的特性有些差异 你常常能认出较新的函数 因为它们的名字原来的函数名相似(象CreateWindow/CreateWindowEx CreateTypeLib/CreateTypeLib 以及我最喜欢的CreatePen/CreatePenIndirect/ExtCreatePen

  所有这些问题都使程序员觉得Windows开发很难 随着 NET平台的出现 温柔终于为叫苦不迭的开发人员提供了一个完全面向对象的开发平台 平台服务现在被分成为单独的名字空间(如 System Collections System Data System IO SystemSecurity System Web等等)并且每一个名字空间包含一组允许访问平台服务的相关类

  因为类方法可以重载 行为差别不大的方法具有相同的名字 并且只有从原型中才能看出差别来 例如 一个类可能提供三个不同版本的CreatePen方法 所有方法都做相同的事情 即创建一支笔 但是 每一个方法都有不同的参数集并且行为不太一样 将来微软还要创建第四个CreatePen方法并且与前面的类方法配合默契

  因为所有的平台服务都通过这种面向对象的方式来实现 所以软件开发者应该对面向对象的编程有所理解 面向对象的方法还带来了其它的一些特点 如使用继承和多态性很容易创建专门版本的基类库类型 我再次强烈建议要熟练掌握这些概念 这对于使用微软的 NET框架很重要

  System Object在 NET中 每一个对象都是从System Object派生而来 也就是说下面的两种类型定义(使用C#)是相同的 class Jeff   和class Jeff : System Object     因为所有对象都是从System Object派生出来的 从而可以保证每一个对象具有最小的功能集 表一是System Object中的公共方法

  公共语言运行时需要所有的对象都要用new操作符创建(调用newobj IL指令) 下列代码示范了如何创建Jeff类型(已在前面声明)的对象实例

  Jeff j = new Jeff( ConstructorParam )

  new操作符根据指定的类型需要从堆中分配字节数来创建对象 它初始化对象的开销成员 每一个对象都会有一些公共语言运行时用来管理对象的附加字节 如对象的许表指针以及对同步快的引用

  调用类的构造函数时 传递的参数在new语句中指定(例子中是串 ConstructorParam ) 注意大多数语言会编译构造函数以便它们调用基类构造函数 但这在公共语言运行时中是不需要的

  在new实现了所有我所提到的操作后 它返回新创建对象的引用 在例子代码中 这个引用被存储在变量j中 它的类型是Jeff

  另外 new操作符没有配对操作(delete) 即没有方法显式地释放或销毁对象 公共语言运行时提供自动地探测的垃圾回收环境 当对象不再被使用或不再被访问时自动地释放和销毁对象 有关这个主题将在下次的讨论中提出

  数据类型的强制转换

  在编程过程当中 对象从一个数据类型到另一个数据类型的强制类型转换是十分常见的 在这一部分 我将讨论对象的强制数据类型转换规则 为此 先看下列代码

  System Object o = new Jeff( ConstructorParam )

  先前的代码编译通过并正确执行是因为有一个隐含的强制类型转换 new操作符返回Jeff的一个引用类型 但o是一个System Object的引用类型 因为所有的类型(包括Jeff类型)都能被强制转换为System Object 隐含的强制类型转换是成功的 但是 如果执行下面的代码 就会有编译器错误 因为编译器不提供基类型到派生类型的强制类型转换

  Jeff j = o

  为了能通过编译 必须插入如下的显式强制类型转换

  Jeff j = (Jeff) o

  现在就可以编译通过并成功执行

  再来看另外一个例子

  System Object o = new System Object()

  Jeff j = (Jeff) o

  第一行创建了一个System Object类型对象 第二行代码试图将System Object引用类型转换为Jeff引用类型 两行代码都能编译通过 但是在执行的时候 第二行代码产生一个InvalidCastException异常 如果捕获不到这个异常 将强制应用程序终止

  当第二行代码执行时 公共语言运行时查证o所指的对象就是Jeff类型对象(或任何Jeff派生类型) 如果是 则公共语言运行时允许强制类型转换 否则 如果o所指的对象与Jeff类型无关 或是一个Jeff的基类 则公共语言运行时会预防这种不安全的强制类型转换并产生InvalidCastException异常

  C# 使用as操作符提供另一种方法来实现强制类型转换 Jeff j = new Jeff(); // 创建一个新的Jeff 对象System Object o = j as System Object; // 强制转换 j 为一个System Object对象// 现在o 指Jeff 对象as操作符试图强制转换一个对象为指定的类型 但与通常的强制转换不一样 如果对象的类型强制转换不成功 结果会是null as操作符决不会掷出异常 当引用有毛病的强制类型转换发生时 将产生NullReferenceException异常 下列代码示范了这种情况 System Object o = new System Object(); //创建一个新的Object 对象Jeff j = o as Jeff; //强制转换 o 为一个Jeff对象// 上面的强制转换失败 不会有异常掷出 而j会被置为nullj ToString(); // 访问j时产生一个NullReferenceException 异常除了as操作符以外 C#还提供一个is操作符 它检查是否一个对象实例与给定的类型兼容并判断结果是True或是False Is操作符不会产生异常 System Object o = new System Object();System Boolean b = (o is System Object); // b 是 TrueSystem Boolean b = (o is Jeff); // b 是 False注意 如果对象引用是null is操作符总是返回False 因为得不到对象来检查其类型 为了肯定你理解了刚才所说的内容 假设下列两各类定义存在 class B int x;class D : B int x;    现在 参见图二看看哪一行代码通过编译并执行成功(ES) 哪一行代码导致编译器错误(CE) 哪一行代码导致公共语言运行时错误(RE)

  集合与名字空间

  类型集可以被分组成集合(一个或多个文件集)并且被展开 在一个集合中可以只存在单独的名字空间 对应用程序开发人员来说 名字空间就像有关联的类型的逻辑分组 例如 基本类库集合包含许多名字空间 System名字空间包括Object基类型 Byte Int Exception Math和Delegate之类的核心低级类型 而System Collections名字空间包括的类型如AarryList BitAarry Queue和Stack

  对于编译器来说 名字空间只不过是名字较长的的类型名 以及其唯一性是用句点分隔某些符号名来保证的 对于编译器而言 System名字空间中的Object类型只不过是用一个叫做System Object的类型来表示 同样 System Collections名字空间中的Queue类型简单地用标示符System Collections Queue来表示

  运行时引擎不知道关于名字空间的任何信息 当你访问一个类型时 公共语言运行时只需要知道完整的类型名字以及哪一个集合包含这个类型的定义 以便公共语言运行时能正确加载集合 从而找到要访问的类型并处理之

  编程人员通常都想用最简练的方法来表达算法 但用完全限定名引用每一个类类型的话极其麻烦 因此 许多编程语言提供一条语句来指示编译器添加各种前缀到类型名 直到实现一个匹配 当用C#编程时 我经常在源代码的最前面是用下面的语句

  using System

  当我在代码中引用一个类型时 编译器需要保证这个类型被定义过并且我的代码要以正确的方式访问这个类型 如果编译器不能找到指定的类型 它试图将 System 添加到类型名并检查产生的类型名字是否与现存的类型名匹配 前面的代码行允许我在代码中使用Object 并且编译器将自动将名字展开为System Object 我肯定你能轻松想象这样省去了多少键盘输入

  当进行类型定义的检查时 编译器必须知道哪一个集合包含了这个类型 以便这个集合的信息和类型信息能被送到结果文件中 为了获得集合信息 你必须将定义了任何引用类型的集合传给编译器

  正如你所设想的一样 这种设计存在一些潜在的问题 为了编程方便 你应该避免创建名字冲突的类型 但是在某些情况中 它完全不可能 NET鼓励组件重用 你的应用程序可以利用Microsoft所创建的组件 同时 你也可以用Richter创建的另一个组件 这些公司的组件可能都提供了一个叫做FooBar的类型 Microsoft的FooBar所做的事情与Richter的FooBar所做的事情完全不同 在这种情况下 你无法控制类类型的命名 为了引用Microsoft的FooBar 你使用Microsoft FooBar 为了引用Richter的FooBar 你使用Richter FooBar

  在下列的代码中 对FooBar的引用是不明确的 编译器报告一个错误也就罢了 但是实际上C#编译器挑选FooBar类型的一种可能的情况 直到运行时你才能发现问题

  using Microsoft;using Richter;class MyApp method void Hi() FooBar f = new FooBar(); // Ambiguous piler picks为了排除这种不明确的引用 你必须显式地告诉编译器 你想创建哪一个FooBar using Microsoft;using Richter;class MyApp method void Hi() Richter FooBar f = new Richter FooBar(); // 明确引用另一种语句形式是允许你为单独类型创建别名 如果你只使用名字空间中的几种类型并且不想用所有的名字空间类型污染整个名字空间的话 这种方法很方便 下列代码示范了另一种解决类型不明确问题的方法 // 定义RichterFooBar 为Richter FooBar的别名using RichterFooBar = Richter FooBar;class MyApp method void Hi() RichterFooBar f = new RichterFooBar(); // 不会出错    这种方法对于消除类型歧义有用 但不尽人意的地方仍然存在 假设澳大利亚的飞镖(Boomerang)公司(简称ABC)和阿拉斯加的船舶(Boat)公司(也简称ABC)两家公司各自创建了一个类型 可能两家公司都创建了叫做ABC的名字空间 在名字空间中包含一个叫做BuyProduct的类型 任何试图开发需购买飞镖和船舶应用程序的人将会陷入麻烦 除非编程语言提供编程方法来区分两家公司的集合 而不仅仅是两家公司的名字空间

  不幸的是C#语言只支持名字空间 并不提供任何方式来详细说明集合 但实际上碰到这个问题的时候并不多 属于罕见问题 如果是设计希望第三方使用的组件类型 推荐在一个名字空间中定义类型 以便编译器轻松排除类型问题 事实上 应该使用公司全名(不是只取首字母)作为最高级名字空间名来降低冲突的可能性 你能看到Microsoft使用 Microsoft 作为名字空间

  在代码中写一个名字空间声明来创建名字空间是一件很简单的事情 就像下面这样

  namespace CompanyName // CompanyNameclass A // CompanyName Aclass B // CompanyName A Bnamespace X // CompanyName Xclass C // CompanyName X C   注意名字空间是隐含的公共类型(public) 不能通过任何访问修饰符改变这一点 但可以在内部的名字空间中定义类型(不能在集合外面使用)或者在公共的名字空间中定义类型(能被任何集合访问) 名字空间只表示逻辑上的限制策略 可访问性和包装是通过将名字空间放入一个集合来完成的

cha138/Article/program/net/201311/12578

相关参考

知识大全 .NET编程语言的未来

.NET编程语言的未来  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  对NET平台的编程语言的当

知识大全 在Java平台上进行多线程编程的缺陷

在Java平台上进行多线程编程的缺陷  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!Java语言的并

知识大全 在Java平台上进行多线程编程的缺陷[1]

在Java平台上进行多线程编程的缺陷[1]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 

知识大全 在Java平台上进行多线程编程的缺陷[2]

在Java平台上进行多线程编程的缺陷[2]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  争用条

知识大全 微软.NET 4发布 18个月的明星

微软.NET4发布18个月的明星  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  经过个月的中断上

知识大全 微软地图MapPoint2004编程简介(图)

微软地图MapPoint2004编程简介(图)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  如

知识大全 微软同步框架中的自定义数据同步基础

  MicrosoftSyncFramework(MSF)为我们提供了进行同步应用开发的基础框架和API这些API即有基于托管代码的也有基于非托管代码的也就是说我们既可以开发基于NET平台使用托管AP

知识大全 C#编程三步走之一

C#编程三步走之一  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  C#是微软NET架构的主力开发

知识大全 VB.NET的新的面向对象能力

VB.NET的新的面向对象能力  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  面向对象的编程在V

知识大全 探讨C#编程语言的未来

探讨C#编程语言的未来  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  作为微软NET框架的标志性