委托的匿名方法,以及在协变与逆变中的应用

委托的匿名方法
    这几天在看微软的MVP设计模式的例子的时候,偶然发现它将DropDownList的SelectIndexChange事件委托直接实例化成一个不带任何参数匿名方法。
如下:

  1. this.customerDropDownList.SelectedIndexChanged += delegate
  2.                                                               {
  3.                                                                   presenter.DisplayCustomerDetails();
  4.                                                               };

这让我不禁起了疑惑。SelectedIndexChanged事件委托应该要带有一个参数EventArgs才对啊。为什么它用这函数实例化呢?
几经查询,终于明白了,不带括弧delegate 关键字将定义一种特殊的匿名方法,它可以指派给具有任何签名的任何委托。就如上面的代码一样。如果使用匿名方法,则不必创建单独的方法,因此减少了实例化委托所需的编码系统开销。

 

委托的协变与逆变
    协变允许方法具有的派生返回类型比委托中定义的更多。而委托还有一种逆变,逆变允许方法具有的派生参数类型比委托类型中的更少。将方法签名与委托类型匹配时,协变和逆变提供了一定程度的灵活性。
下面分别提供一个简单的例子说明一下。

 

1.协变。
     以下委托将定义为具有Human返回类型的委托,而实例化委托的方法中有一个返回类型是Women类型的。Women类型是由Human类型派生的。

 

  1. class Human
  2. {
  3.     public override string ToString()
  4.     {
  5.         return "human";
  6.     }
  7. }
  8. class Women: Humen
  9. {
  10.     public override string ToString()
  11.     {
  12.         return "women";
  13.     }
  14. }
  15. class Program
  16. {
  17.     /// <summary>
  18.     /// 定义一个返回类型为Human的委托。
  19.     /// </summary>
  20.     /// <returns>返回一个Human对象。</returns>
  21.     public delegate Human GetHumanHandler();
  22.     public static Human GetHuman()
  23.     {
  24.         Human human;
  25.         if (isWomen)
  26.         {
  27.             human = new Women();
  28.             Console.WriteLine(human);
  29.             return human;
  30.         }
  31.         human = new Human();
  32.         Console.WriteLine(human);
  33.         return human;
  34.     }
  35.     public static Human GetWomen()
  36.     {
  37.         Women human = new Women();
  38.         Console.WriteLine(human);
  39.         return human;
  40.     }
  41.     static void Main(string[] args)
  42.     {
  43.         //命名方法
  44.         GetHumanHandler handler1 = GetHuman;
  45.         //匿名方法
  46.         GetHumanHandler handler2 = delegate
  47.                     return GetWomen(); };
  48.         handler1.Invoke(false);
  49.         handler2.Invoke(true);
  50.     }
  51. }

2.逆变
    以下委托将定义为一个带有Human类型参数的委托何一个带有Women类型参数的委托。Women类型是由Human类型派生的。
而实例化委托的方法中只是一个带有Human类型参数的方法。两个委托共用一个方法实例。

 

  1. class Human
  2. {
  3. }
  4. class Women : Human
  5. {
  6. }
  7. class Program
  8. {
  9.     public delegate void HumanInfoPrintHandler(Human human);
  10.     public delegate void WomenInfoPrintHandler(Women human);
  11.     public static void HumanInfoPrint(Human human)
  12.     {
  13.         if (human is Women)
  14.         {
  15.             Console.WriteLine("women");
  16.         }
  17.         else
  18.         {
  19.             Console.WriteLine("human");
  20.         }
  21.     }
  22.     static void Main(string[] args)
  23.     {
  24.         HumanInfoPrintHandler handler1 = HumanInfoPrint;
  25.         WomenInfoPrintHandler handler2 = HumanInfoPrint;
  26.         handler1.Invoke(new Human());
  27.         handler2.Invoke(new Women());
  28.     }
  29. }


MSDN官方资料请参看(C#编程指南)
http://msdn.microsoft.com/zh-cn/library/ms173174(VS.80).aspx
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值