科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道微软 .NET 在新的平台上编程(一)

微软 .NET 在新的平台上编程(一)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

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

作者:中国IT实验室 来源:中国IT实验室 2007年9月11日

关键字: 编程

  • 评论
  • 分享微博
  • 分享邮件
  

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

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

    真正的面向对象设计

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

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

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

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

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

    数据类型的强制转换

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

    System.Object o = new Jeff("ConstructorParam1");

    先前的代码编译通过并正确执行是因为有一个隐含的强制类型转换。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异常。

 

[1] [2] [3] 下一页  

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章