[原] C# 3.0的委托(delegate)及Lambda表达式应用实例

C# 3.0新增了很多特性,其中委托(delegate)配合Lambda表达式使得程序简洁了很多。
我也就来尝尝鲜(其实也不算鲜了,C# 4.0都出来了。。。),说说我的应用实例:读取Micaps(一种气象上用的软件)数据文件。
Micaps有各类数据文件,比如第一类表示地面填图,格式是:
diamond 1 屏幕上需显示的内容
年 月 日 时次 总站点数
区站号 经度 纬度 ……(后面的你也不关心,就略掉了)

第二类表示高空填图,格式是:
diamond 2 屏幕上需显示的内容
年 月 日 时次 层次 总站点数
…… (参数与地面当然不一样)

如上,第一行是所有文件的通用信息,表示了该文件的类型、标题等,后面就是具体数据,每类文件格式不一。
于是,就要针对不同类型写不同的处理方法,但是,打开文件、关闭文件、检验第一行 这些又是一样的,导致代码重复。
这时候,委托就非常有意义:可以在父类里完成通用处理,而具体的数据处理通过委托交给子类具体负责。

  1. /// <summary>
  2. /// Micaps 数据格式基类
  3. /// v1.0  090301, bianbian.org
  4. /// </summary>
  5. public abstract class Base
  6. {
  7.     //文件数据类型
  8.     protected int DataType { get; set; }
  9.     //委派:LoadHandler
  10.     protected delegate bool LoadHandler(StreamReader reader);
  11.  
  12.     /// <summary>
  13.     /// 读Micaps数据文件
  14.     /// </summary>
  15.     /// <param name="path">文件路径</param>
  16.     /// <param name="handler"></param>
  17.     /// <returns>true:成功  false:失败</returns>
  18.     protected bool Load(string path, LoadHandler handler)
  19.     {
  20.         StreamReader reader = null;
  21.         try
  22.         {
  23.             reader = new StreamReader(path);
  24.             //micaps数据第一行: "DIAMOND 类型编号 title"
  25.             string line = reader.ReadLine();
  26.             /*此处是对第一行的类型检查,跟本文主题无关,略)*/
  27.             //后续load交给子类完成
  28.             return handler(reader);
  29.         }
  30.         catch (Exception)
  31.         {
  32.             return false;
  33.         }
  34.         finally
  35.         {
  36.             if(reader != null)
  37.                 reader.Close();
  38.         }
  39.     }
  40. }

如上,基类创建了LoadHandler这个委托类型,使得可以动态调用子类具体的操作。
如下是第一类数据格式的子类

  1. /// <summary>
  2. /// Micaps第一类数据格式(地面):
  3. /// </summary>
  4. public class Surface : Base
  5. {
  6.     public Surface()
  7.     {
  8.         DataType = 1;
  9.     }
  10.  
  11.     public bool Load(string path)
  12.     {
  13.         //C# 3.0 Lambda表达式,实际建立了匿名delegate方法
  14.         return Load(path, (StreamReader reader) =>
  15.         {
  16.             /*此处为具体的读取数据处理方法,每个子类不同*/
  17.             return false;
  18.         });
  19.     }
  20. }

其中的 (StreamReader reader) => {} 就是传说中的Lambda表达式,实际相当于:
delegate(StreamReader reader) {}
当然,C#3.0编译器够聪明,第14行甚至可以写成 return Load(path, reader => ...
不过我觉得这样写以后看代码可能会晕,既然编译结果是一样的,何必省那么几个字呢。。。。
关于C#1.0 2.0 3.0的delegate演变可以看看这篇文章,总结得很好了:

http://huan-lin.blogspot.com/2009/01/delegate-revisited-csharp-1-to-2-to-3.html

©2012 便便代码人生. All Rights Reserved.

. 标签: C#, delegate, Lambda, Micaps, 委派

遵守创作共用协议,转载请链接形式注明来自http://bianbian.org 做人要厚道

相关日志

posted @ 2009-03-02 11:28  便便嘘嘘  阅读(200)  评论(0编辑  收藏  举报