泛型

【回目录】

泛型是C# 2.0版本才开始有的语言特性,不过“泛型”这个概念并不是最先出现在编程领域的,例如C++中的模板。

List<T>就是一个泛型应用。你可以在需要时声明一个强类型的List<T>实例,然后随意地往里面添加、删除和查询同一类型的元素。泛型就是一个非常方便的数据结构,长期使用C#的朋友大多都常常用到泛型。本文就简单地通过创建自己的泛型类来介绍一下泛型,希望能够加深初学者对泛型(这个名字很奇怪的东西)的认识和理解。

用到泛型的时候你就会发现,泛型其实就像一个口袋,你可以很方便地往里面装东西,只是在第一次使用这个口袋的时候要注意声明它只能装什么样类型的东西,以后就不能装错了。那么我们就用钱包为例吧,我们首先描述一下钱包。钱包的用途不外乎是装点儿东西,当然,除了钱还可以装其它很多东西,例如银行卡、便签条、照片等等,但是这些东西有些共同的地方,至少是尺寸方面不能超过钱包的限制,谁可以把冰箱也揣在钱包里呢?因此,我们在设计能装进钱包的物品的类的时候就要考虑到尺寸的因素。

   1: public class WalletThingBase
   2: {
   3:     protected readonly int MaxLength = 10;
   4:     protected readonly int MaxWidth = 7;
   5:     protected readonly int MaxThickness = 1;
   6:  
   7:     private int _length = 0;
   8:     public int Length
   9:     {
  10:         get { return this._length; }
  11:         set
  12:         {
  13:             if (value <= 0 || value > this.MaxLength)
  14:             {
  15:                 throw new ArgumentException("Length is invalid.");
  16:             }
  17:  
  18:             this._length = value;
  19:         }
  20:     }
  21:  
  22:     private int _width = 0;
  23:     public int Width
  24:     {
  25:         get { return this._width; }
  26:         set
  27:         {
  28:             if (value <= 0 || value > this.MaxWidth)
  29:             {
  30:                 throw new ArgumentException("Width is invalid.");
  31:             }
  32:  
  33:             this._width = value;
  34:         }
  35:     }
  36:  
  37:     private int _thickness = 0;
  38:     public int Thickness
  39:     {
  40:         get { return this._thickness; }
  41:         set
  42:         {
  43:             if (value <= 0 || value > this.MaxThickness)
  44:             {
  45:                 throw new ArgumentException("Thickness is invalid.");
  46:             }
  47:  
  48:             this._thickness = value;
  49:         }
  50:     }
  51:  
  52:     public WalletThingBase(int length, int width, int thickness)
  53:     {
  54:         this.Length = length;
  55:         this.Width = width;
  56:         this.Thickness = thickness;
  57:     }
  58: }

接下来我们来派生几个类吧,银行卡以及信用卡:

   1: public class BankCard : WalletThingBase
   2: {
   3:     public int ID { get; set; }
   4:     public string Name { get; set; }
   5:     public string Password { get; set; }
   6:  
   7:     public BankCard(int length, int width, int thickness)
   8:         : base(length, width, thickness)
   9:     {
  10:     }
  11: }
  12:  
  13: public class CreditCard : BankCard
  14: {
  15:     public decimal Overdraft { get; set; }
  16:  
  17:     public CreditCard(int length, int width, int thickness)
  18:         : base(length, width, thickness)
  19:     {
  20:     }
  21: }

通过上面的代码可以看出,在创建派生自WalletThingBase类的所有类的时候,都会先检验其尺寸是否超标,如果是尺寸过大就不允许创建,也就表示你不能把它放进你的钱包。显然,银行卡尽管规格各异,但都是可以的。

接下来,我们就要来设计钱包这个类了。我们可以借助List<T>来简化我们的设计工作,最需要注意的其实就是严格把关,凡是非WallThingBase派生类都不允许进入,另外,还得简单提供一些放东西和取东西的函数,这样,一个基本的钱包就设计出来了。

   1: public class Wallet<T> : CollectionBase
   2: {
   3:     public Wallet()
   4:     {
   5:         Type baseType = typeof(T).BaseType;
   6:  
   7:         while (baseType != null
   8:             && baseType != typeof(Object)
   9:             && baseType.BaseType != typeof(Object))
  10:         {
  11:             baseType = baseType.BaseType;
  12:         }
  13:  
  14:         if (baseType != typeof(WalletThingBase))
  15:         {
  16:             throw new Exception(typeof(T).ToString() + " cannot be put into wallet.");
  17:         }
  18:     }
  19:  
  20:     public T this[int index]
  21:     {
  22:         get { return (T)List[index]; }
  23:         set { List[index] = value; }
  24:     }
  25:  
  26:     public int Add(T item)
  27:     {
  28:         return List.Add(item);
  29:     }
  30:  
  31:     public void Remove(T item)
  32:     {
  33:         List.Remove(item);
  34:     }
  35: }

泛型是一种很具有亲和力的语言特性,很容易让人接受也很容易让人喜欢上它,借助泛型的便利,尽情享受C#开发乐趣吧!

eWallet

posted @ 2008-06-16 18:08  麦机长  阅读(6139)  评论(8编辑  收藏  举报