码迷,mamicode.com
首页 > 其他好文 > 详细

委托的发展(二)

时间:2018-05-08 11:12:05      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:console   foreach   color   文字   bin   class   不兼容   匹配   tac   

嗯~~,其实在C#1看来委托语法看起来似乎并不太坏——语言以围绕Delegate.Combine,Delegate.Remove以及委托实例的调用提供了语法糖。

表面上一切都在正常的轨道上,但是感觉不太对。

很难确切的描述C#1的委托创建表达式为什么会令人不快,但他们确实如此。

在C#1中我们先写好一连串事件处理程序,然后到处写new。这显得很多余,很凌乱,因为事件本身已经指定了它要使用那个委托类型。

可能你会有不同意见,但是由于代码中的文字量过多,会妨碍我们阅读,并会使我们分心而忽略了真正该注意的代码。

委托的协变性与逆变型,暂时先不所!

*C#2委托的进步阶梯

        delegate void TestDelegate(string x);
        public class Snippet
        {
            public void TestAction(string x)
            {
                Console.WriteLine("Hellow");
            }
        }

        public class Derived : Snippet
        {
            public void TestAction(object x)
            {
                Console.WriteLine("Hi");
            }
        }

如果这样调用这个委托的话:

          Derived x = new Derived();
                TestDelegate test = new TestDelegate(x.TestAction);
                test("test");

上面有两个类,Snippet与Derived,并且Derived继承自Snippet

在C#1中会输出"Hellow"。因为object参数那个方法与委托TestDelegate不兼容。

但在C#2中,它是兼容的,他会输出“Hi”。由于是在另一个派生的类型中声明的,所以选中的是这个方法,。

*C#2匿名方法

在C#1,你只需要一个委托,做一件非常非常小的事情,但也必须创建一个完整的新方法。该方法表示的行为只和原始方法有关,但现在却对整个类公开。

这一切都让人呕吐,所以C#2引入了  匿名方法

漂亮的解决了此问题。

按照不太正式的说法,匿名方法允许你指定一个内联委托实例的操作,作为创建委托实例表达式的一部分。

匿名方法还以 闭包 的形式提供了一些更加强大的行为。

与下面的Action一起来做一个例子吧

*C#2引入了一个泛型委托类型Action<T>

他的签名非常简单: 就是一个无返回值的只有一个参数的名叫Action的泛型委托

 public delegate void Action<T>(T obj);

使用匿名方法加Action泛型委托来:输出List<int>的总和

 Action<List<int>> list = delegate (List<int> x)
 {
      int sum = 0;
      foreach (int i in x)
      {
         sum += i;
      }
       Console.WriteLine("总和:" + sum );
 };
  list(List<int>); //执行

 首先是匿名方法的语句:首先是delegate关键字,再是参数(如果有的话),随后是一个代码块,定义的对委托实例的操作。

 看的出来这个匿名方法声明了一个int变量,然后循环List集合,累加到int变量上,然后输出这个List总和。

提醒一点,逆变型不适用于匿名方法:必须指定和委托类型完全匹配的参数类型。

*匿名方法的返回值

Action<T>委托的返回类型是void,所以不必从匿名方法中返回任何东西。在某种情况下需要返回值怎么办呢?

使用.NET2.0中的Predicate<T>委托类型。下面给出它的签名:

public delegate bool Predicate<T>(T obj);

它是一个Predicate<T>的泛型委托实例,返回值时bool类型,而且有一个参数。

谓词(Predicate)通常用于过滤和匹配,例如,可以利用代码清单来过滤一个列表,使之只包含偶数元素。

来用一下,创建一个Predicate<T>实例,其返回值指出传入的实参是奇数还是偶数。

        Predicate<int> isEven = delegate (int x)
            {
                return x % 2 == 0;
            };

            Console.WriteLine(isEven(1));
            Console.WriteLine(isEven(6));

新的语法(匿名方法),我想把它当做一个普通方法来对待,并返回一个恰当的值。你可能以为还要在靠近delegate关键字的地方声明一个返回类型,但那是没有必要的。

因为编译器只需检查是否所有可能的返回值都兼容于委托类型(编译器会尝试将匿名方法转换成这个委托类型)声明的返回类型。

*小结

C#2根本性的改变了委托的创建方式,这样我们就能在。NET Framework的基础上采取一种更函数化的编程风格。

与.Net1.0/1.1相比,2.0有更多以委托作为参数的方法

2.0委托改动非常多甚至可以说是变革一样。我讲述了不到十分之一。

只是大体讲了讲委托的进化,而没有说出他的内在变化,逆变型与协变性,包括闭包,捕获变量等等。。。

太多了。。。以后再补充吧

委托的发展(二)

标签:console   foreach   color   文字   bin   class   不兼容   匹配   tac   

原文地址:https://www.cnblogs.com/yingxl/p/9003632.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!