一、 泛型简介
泛型(Generic)是C# 2.0新增的概念之一,其宗旨是避免进行强制类型转换的需求,提高类型安全性,减少需要的装箱量并且让程序员更轻松地创建泛型化的类和方法。泛型类和方法接受所谓的“类型参数”,由它们确定要操作的对象的类型。

二、 问题的提出
.NET框架2.0通过System.Collections.Generic命名空间提供了许多集合类和接口的泛型版本。
.NET框架类库已经包含了大量现成的泛型类。当然,用户也可以根据自己的需要定制泛型类。不知何原因,微软恰好在System.Collections.Generic命名空间中遗漏了二叉树类。须知,二叉树是一种非常有用的数据结构,可用它实现大量的操作,其中包括以极快的速度来排序和搜索数据。

在本文中,我们将使用.NET 2.0泛型概念构造一棵基本的二叉树,使其能容纳多种类型的数据。

三、 使用泛型构造二叉树类实例
由于二叉树类在许多程序中都能用到;所以,最好我们把它做成一个类库以便重用。然后,可以到处重用这个类,而无需复制源代码并重新编译它。

【提示】在.NET中,类库是一系列已经编译的类的集合,所有这些类都存储在一个程序集中。程序集是一个通常采用.dll扩展名的文件。其它项目和应用程序可以添加对程序集的一个引用,然后使用using语句,将它的命名空间带入自己的范围中,从而利用类库中的内容。

启动Visual Studio 2005。选用“类库”模板来创建一个新的Visual C#项目,并将项目命名为BinaryTree。然后,在解决方案资源管理器中,将文件名Class1.cs改变为Tree.cs。

接下来,对Class1类的定义作如下修改,最后代码如下所示:
    
    
    
    
namespace BinaryTree { public class Tree<T> where T : IComparable<T> { private T data; private Tree<T> left; private Tree<T> right; //……
【提示】泛型和约束常常是联系在一起使用的。通过约束,可以将一个泛型类的类型参数限制成实现了一系列特定接口的类型(所以它们能够提供由那些接口定义的方法)。
在本例中,我们修改Tree类的定义,指定类型参数T必须是实现了泛型IComparable接口的一个类型。

【提示】如果我们需要创建一个类,要求它能够根据某种排序方式对值进行比较,那就要实现IComparable接口。此接口包含一个CompareTo方法,由它来获得单个参数,并返回一个整数以指出比较结果。
在上面的Tree类中添加了三个私有变量,只要有二叉树概念,其含义自明,不多赘述。接下来,我们在类中添加两个方法Insert和WalkTree,分别用于插入结点和遍历二叉树。相应代码如下: 
    
    
    
    
// 此方法在二叉树中插入一个值为T的结点。 // 注意,因为用户可以使用构造器在树中插入初始的根结点,所以在此方法中 // 我们树是非空的。 public void Insert(T newItem) { T currentNodeValue = this.NodeData; // CompareTo含义上面已作解释,用于判断当前节点值是否大于新项 if (currentNodeValue.CompareTo(newItem) > 0) { if (this.LeftTree == null) { this.LeftTree = new Tree<T>(newItem); } else { this.LeftTree.Insert(newItem); } } else { if (this.RightTree == null) { this.RightTree = new Tree<T>(newItem); } else { this.RightTree.Insert(newItem); } } } // 此方法负责遍历二叉树-把结点值转换为字符串,并输出到控制台 public void WalkTree() { if (this.LeftTree != null) //判断左结点是否为空 { this.LeftTree.WalkTree();//非空,则递归遍历左子树 } Console.WriteLine(this.NodeData.ToString());//输出到控制台 if (this.RightTree != null) //判断右结点是否为空 { this.RightTree.WalkTree();//非空,则递归遍历右子树 } }
四、 测试Tree

 为了测试上面库中的二叉树类,选择“文件→新建→添加项目”,选用“控制台应用程序”模板来添加一个新项目,并将项目命名为BinaryTreeTest。

  在解决方案资源管理器中,选择BinaryTreeTest项目并将之设置为启动项目。
选择“项目→添加引用”。单击“项目”标签,单击BinaryTree项目,并确定。
最后,我们在Main方法中加入如下语句进行测试: 
    
    
    
    
static void Main( string [] args) { Tree < int > tree1 = new Tree < int > ( 10 ); tree1.Insert( 9 ); tree1.Insert( 6 ); tree1.Insert( 5 ); tree1.Insert( - 12 ); tree1.Insert( 177 ); tree1.Insert( 0 ); tree1.Insert( 9 ); tree1.Insert( 9 ); tree1.WalkTree(); Tree < string > tree2 = new Tree < string > ( " Hello " ); tree2.Insert( " World " ); tree2.Insert( " How " ); tree2.Insert( " Old " ); tree2.Insert( " Are " ); tree2.Insert( " You " ); tree2.WalkTree(); Console.Read(); }
运行结果如下图所示: 
  
五、 小结
“泛型”概念在增加类型安全的同时,也大大提高了软件的模块化开发。在本文中,我们基于泛型概念创建了一棵简单的二叉树。当然,在实践中还有待于大量的“美化”。