设为首页  
联系我们  
加入收藏  
网页制作 冲浪宝典 图形图像 操作系统 软件教学 编程开发 认证考试 安全技术 站长专区 文学驿站 娱乐天地 游戏天地 办公软件
文章搜索
您的位置: 首页 >> 文章首页 >> 编程开发 >> 网站制作技术 >> C# 中的泛型
精品推荐
网站制作技术点击TOP10
·网页打印问题,打印设置,打印预览,打印分页,纵打,横打及页面的边距
·使用PHP DOM-XML创建和解析XML文件
·Asp.net可输入下拉框服务器控件
·用createPopup()方法来模似透明网页窗体
·Shake_JS选色器
·嵌入式网站媒体播放器ExoBUD MP(II) v4.1tc+
·仿QQ2003风格的导航栏
·在 Windows 系统安装虚拟网卡
·全角/半角的转换函数
·聊天室内看人家的IP
编程开发点击TOP10
·数字小键盘指法练习
·ASP.NET 程序中常用的三十三种代码
·C++经典电子书下载
·java笔试题
·Modem 常用AT指令集
·异常java.sql.SQLException: Io exception:The Network Adapter could not establish connection
·MyEclipse 下开发JSF教程
·挂钩Windows API
·MYSQL 新版出现 Client does not support authentication protocol requested by server; consider upgrading MySQL client解决办法
·.NET 初 级 读 本
精选专题

C# 中的泛型

作者: 来源: 时间:2007-8-4 11:05:48

C# 中的泛型(1)

术语表:
generiCS:泛型

type-safe:类型安全

collection: 集合

compiler:编译器

run time:程序运行时

object: 对象

.NET library:.Net类库

value type: 值类型

box: 装箱

unbox: 拆箱

implicity: 隐式

eXPlicity: 显式

linked list: 线性链表

node: 结点

indexer: 索引器

简介
Visual C# 2.0 的一个最受期待的(或许也是最让人畏惧)的一个特性就是对于泛型的支持。这篇文章将告诉你泛型用来解决什么样的问题,以及如何使用它们来提高你的代码质量,还有你不必恐惧泛型的原因。

泛型是什么?
很多人觉得泛型很难理解。我相信这是因为他们通常在了解泛型是用来解决什么问题之前,就被灌输了大量的理论和范例。结果就是你有了一个解决方案,但是却没有需要使用这个解决方案的问题。

 

这篇文章将尝试着改变这种学习流程,我们将以一个简单的问题作为开始:泛型是用来做什么的?答案是:没有泛型,将会很难创建类型安全的集合。

 

C# 是一个类型安全的语言,类型安全允许编译器(可信赖地)捕获潜在的错误,而不是在程序运行时才发现(不可信赖地,往往发生在你将产品出售了以后!)。因此,在C#中,所有的变量都有一个定义了的类型;当你将一个对象赋值给那个变量的时候,编译器检查这个赋值是否正确,如果有问题,将会给出错误信息。

 

在 .Net 1.1 版本(2003)中,当你在使用集合时,这种类型安全就失效了。由.Net 类库提供的所有关于集合的类全是用来存储基类型(Object)的,而.Net中所有的一切都是由Object基类继承下来的,因此所有类型都可以放到一个集合中。于是,相当于根本就没有了类型检测。

 

更糟的是,每一次你从集合中取出一个Object,你都必须将它强制转换成正确的类型,这一转换将对性能造成影响,并且产生冗长的代码(如果你忘了进行转换,将会抛出异常)。更进一步地讲,如果你给集合中添加一个值类型(比如,一个整形变量),这个整形变量就被隐式地装箱了(再一次降低了性能),而当你从集合中取出它的时候,又会进行一次显式地拆箱(又一次性能的降低和类型转换)。

 

关于装箱、拆箱的更多内容,请访问 陷阱4,警惕隐式的装箱、拆箱。

创建一个简单的线性链表
为了生动地感受一下这些问题,我们将创建一个尽可能简单的线性链表(译注:数据结构中最基础的一种结构,不了解的随便翻开一本关于数据结构的书,一般都会出现在第二章)。对于阅读本文的那些从未创建过线性链表的人。你可以将线性链表想像成有一条链子栓在一起的盒子(称作一个结点),每个盒子里包含着一点数据 和 链接到这个链子上的下一个盒子的引用(当然,除了最后一个盒子,这个盒子对于下一个盒子的引用被设置成NULL)。

 

为了创建我们的简单线性链表,我们需要下面三个类:

       1、Node 类,包含数据以及下一个Node的引用。

       2、LinkedList 类,包含链表中的第一个Node,以及关于链表的任何附加信息。

       3、测试程序,用于测试 LinkedList 类。

 

为了查看链接表如何运作,我们添加Objects的两种类型到链表中:整形 和 Employee类型。你可以将Employee类型想想成一个包含关于公司中某一个员工所有信息的类。出于演示的目的,Employee类非常的简单。

 

public class Employee{

  private string name;

  public Employee (string name){

    this.name = name;

  }

 

  public override string ToString(){

   return this.name;

  }

}

 

这个类仅包含一个表示员工名字的字符串类型,一个设置员工名字的构造函数,一个返回Employee名字的ToString()方法。

 

链接表本身是由很多的Node构成,这些Note,如上面所说,必须包含数据(整形 和 Employee)和链表中下一个Node的引用。

 

public class Node{

    Object data;

    Node next;

 

    public Node(Object data){

       this.data = data;

       this.next = null;

    }

 

    public Object Data{

       get { return this.data; }

       set { data = value; }

    }

 

    public Node Next{

       get { return this.next; }

       set { this.next = value; }

    }

}

 

注意构造函数将私有的数据成员设置成传递进来的对象,并且将 next 字段设置成null。

 

这个类还包括一个方法,Append,这个方法接受一个Node类型的参数,我们将把传递进来的Node添加到列表中的最后位置。这过程是这样的:首先检测当前Node的next字段,看它是不是null。如果是,那么当前Node就是最后一个Node,我们将当前Node的next属性指向传递进来的新结点,这样,我们就把新Node插入到了链表的尾部。

 

如果当前Node的next字段不是null,说明当前node不是链表中的最后一个node。因为next字段的类型也是node,所以我们调用next字段的Append方法(译注:递归调用),再一次传递Node参数,这样继续下去,直到找到最后一个Node为止。

 

public void Append(Node newNode){

    if ( this.next == null ){

       this.next = newNode;

    }else{

       next.Append(newNode);

  }

}

 

Node 类中的 ToString() 方法也被覆盖了,用于输出 data 中的值,并且调用下一个 Node 的 ToString()方法(译注:再一次递归调用)。

 

public override string ToString(){

    string output = data.ToString();

 

    if ( next != null ){

       output += ", " + next.ToString();

    }

 

    return output;

}

 

这样,当你调用第一个Node的ToString()方法时,将打印出所有链表上Node的值。

 

LinkedList 类本身只包含对一个Node的引用,这个Node称作 HeadNode,是链表中的第一个Node,初始化为null。

 

public class LinkedList{

  Node headNode = null;

}

 

LinkedList 类不需要构造函数(使用编译器创建的默认构造函数),但是我们需要创建一个公共方法,Add,这个方法将把data存储到线性链表中。这个方法首先检查headNode是不是null,如果是,它将使用data创建结点,并将这个结点作为headNode,如果不是null,它将创建一个新的包含data的结点,并调用headNode的Append方法,如下面的代码所示:

 

public void Add(Object data){

    if ( headNode == null ){

       headNode = new Node(data);

    }else{

       headNode.Append(new Node(data));

    }

}

 

为了提供一点集合的味道,让我们为线性链表创建一个索引器。

 

public object this[ int index ]{

    get{

       int ctr = 0;

       Node node = headNode;

       while ( node != null  && ctr <= index ){

           if ( ctr == index ){

              return node.Data;

           }else{

              node = node.Next;

           }

           ctr++;

        }

    return null;

  }

}

 

最后,ToString()方法再一次被覆盖,用以调用headNode的ToString()方法。

 

public override string ToString(){

    if ( this.headNode != null ){

       return this.headNode.ToString();

    }else{

       return string.Empty;

  }

}

测试线性链表

共4页 9 7 [1] [2] [3] [48 :>

C# 中的泛型 相关文章:
C# 中的泛型 相关软件:
特别声明:本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作者。文章版权归文章原始作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转载的文章有版权问题请联系编辑人员,我们尽快予以更正。
转载请注明来源:http://www.xgdown.com