委托的发展
Posted 樱小露
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了委托的发展相关的知识,希望对你有一定的参考价值。
嗯~~,其实在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委托改动非常多甚至可以说是变革一样。我讲述了不到十分之一。
只是大体讲了讲委托的进化,而没有说出他的内在变化,逆变型与协变性,包括闭包,捕获变量等等。。。
太多了。。。以后再补充吧
以上是关于委托的发展的主要内容,如果未能解决你的问题,请参考以下文章
iOS UIPopoverController委托不工作,仍然是零