委托的发展(二)

内容预览:
  • 可能你会有不同意见,但是由于代码中的文字量过多,会妨碍我们阅读,并会使...~
  • 但在C中,它是兼容的,他会输出“Hi”~
  • 嗯~~,其实在C看来委托语法看起来似乎并不太坏——语言以围绕...~

嗯~~,其实在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委托改动非常多甚至可以说是变革一样。我讲述了不到十分之一。

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

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

以上就是:委托的发展(二) 的全部内容。

本站部分内容来源于互联网和用户投稿,如有侵权请联系我们删除,谢谢。
Email:[email protected]


0 条回复 A 作者 M 管理员
    所有的伟大,都源于一个勇敢的开始!
欢迎您,新朋友,感谢参与互动!欢迎您 {{author}},您在本站有{{commentsCount}}条评论