C#中Predicate<T>与Func<T, bool>泛型委托的用法实例

本文以实例形式分析了C#中Predicate<T>与Func<T, bool>泛型委托的用法,分享给大家供大家参考之用。具体如下:

先来看看下面的例子:

static void Main(string[] args)
{
  List<string> l = new List<string>();
  l.Add("a");
  l.Add("b");
  l.Add("s");
  l.Add("t");  

  if (l.Exists(s => s.Equals("s")))
  {
    string str = l.First(s => s.Equals("s"));
    Console.WriteLine(str);
  }
  else
    Console.WriteLine("Not found");
}

非常简单,就是先判断字符串列表l中是否有s字符串,如果有,则取之并显示出来。从代码中可以看到,l.Exists方法和l.First方法所使用的参数是相同的,但事实是否真是如此?

事实上,List<T>.Exists和List<T>.First的参数分别使用了不同的委托:
Predicate<T>和Func<T, bool>。从函数的签名上看,两者没有区别,都是指代的参数类型为T,返回值为bool的函数,但毕竟两者属于不同的委托类型,因此,下面的代码显然是无法编译通过的:

static void Main(string[] args)
{
  List<string> l = new List<string>();
  l.Add("a");
  l.Add("b");
  l.Add("s");
  l.Add("t");
  Func<string, bool> p = s => s.Equals("s");
  if (l.Exists(p))
  {
    string str = l.First(p);
    Console.WriteLine(str);
  }
  else
    Console.WriteLine("Not found");
}

然而,由于Predicate<T>和Func<T, bool>的确指代的是同一类具有相同签名的函数,而我们往往又不希望将匿名方法的方法体重复地写两次以分别赋予Predicate<T>和Func<T, bool>泛型委托,因此,我们可以自己写一个扩展方法,扩展Func<T, bool>类型以使其能够很方便的转换成Predicate<T>类型:

public static class Extensions
{
  public static Predicate<T> ToPredicate<T> (this Func<T, bool> source)
  {
    Predicate<T> result = new Predicate<T>(source);
    return result;
  }
}

在引入了这个扩展方法之后,我们的代码就可以写成下面的形式:

static void Main(string[] args)
{
  List<string> l = new List<string>();
  l.Add("a");
  l.Add("b");
  l.Add("s");
  l.Add("t");
  Func<string, bool> p = s => s.Equals("s");
  if (l.Exists(p.ToPredicate()))
  {
    string str = l.First(p);
    Console.WriteLine(str);
  }
  else
    Console.WriteLine("Not found");
}

说实话不知为何MS要用这样两种完全不同的泛型委托来实现Exists和First方法,这使得某些情况下代码变得相对复杂,甚至容易出错。我想大概是为了语义清晰的缘故,Exists不过是做判断,因此需要用断言表达式,而在做First操作的时候,则更多的意义上是在迭代地调用指定的方法。学无止境,有待继续探索。

希望本文所述对大家的C#程序设计有所帮助

(0)

相关推荐

  • C#委托与匿名委托详解

    本来是想写一篇<委托与lambda表达式的前世今生>,但仅委托部分已经写了很多内容,于是就此分开关于Lambda表达是的内容后续再写吧. 不知道Lambda表达式是谁发明的,只记得第一次接触Lambda表达式是在使用VS2008的时候,那就先认为是微软发明的吧. Lambda表达式从我接触开始到现在变得越来越流行,Java8中开始支持.kotlin更是对C#,F#做了广泛的抄袭(C#曾几何时不也如此对待过Java嘛).其实这都充分说明了,Lambda表达式的重要性.要搞清楚Lambda首先需要

  • C#中委托和事件的区别实例解析

    本文实例分析了C#中委托和事件的区别,分享给大家供大家参考之用.具体如下: 大致来说,委托是一个类,该类内部维护着一个字段,指向一个方法.事件可以被看作一个委托类型的变量,通过事件注册.取消多个委托或方法.本篇分别通过委托和事件执行多个方法,从中体会两者的区别. 一.通过委托执行方法 class Program { static void Main(string[] args) { Example example = new Example(); example.Go(); Console.Re

  • c# 委托和事件实例学习

    Common.cs: 复制代码 代码如下: using System; using System.Collections.Generic; using System.Text; namespace DelegateAndEvent.App_Code { public class Common { //定义全局变量. public static string txt = ""; #region 定义方法 public string HelloCSharp(string name) { t

  • c#委托与事件(详解)

    引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见到委托和事件就觉得心里别(biè)得慌,混身不自在.本文中,我将通过两个范例由浅入深地讲述什么是委托.为什么要使用委托.事件的由来..Net Framework中的委托和事件.委托和事件对Observer设计模式的意义,对它们的中间代码也做了讨论. 将方法作为方法的参数 我们先不管这个标题

  • 深入理解C#中常见的委托

    一提到委托,浮现在我们脑海中的大概是听的最多的就是类似C++的函数指针吧,呵呵,至少我的第一个反应是这样的.关于委托的定义和使用,已经有诸多的人讲解过,并且讲解细致入微.我就不用多废话了.今天我要说的是C#中的三种委托方式:Func委托,Action委托,Predicate委托以及这三种委托的常见使用场景.Func,Action,Predicate全面解析首先来说明Func委托,通过MSDN我们可以了解到,Func委托有如下的5种类型: 复制代码 代码如下: (1) *delegate TRes

  • C# 委托的三种调用示例(同步调用 异步调用 异步回调)

    首先,通过代码定义一个委托和下面三个示例将要调用的方法: 复制代码 代码如下: public delegate int AddHandler(int a,int b);    public class 加法类    {        public static int Add(int a, int b)        {            Console.WriteLine("开始计算:" + a + "+" + b);            Thread.Sl

  • C#中自定义事件和委托实例

    在windows 编程中用到最多的就是控件的事件了,微软给我们很好的方式,把注意力放到事件执行方法的设计和编码上,但是但我们真正弄懂了事件的真正出发执行原理的话,对我们的编程的提高真是非常榜的,例如在windows编程中 如果我单击了一个button按钮触发了button 的click事件  Button1_Click(){} ,但是有时候我们编程的时候,不但想要触发button 的单击事件,我还想要把其他的时间也要调用下来顺序执行,要实现这种方式,除了在方法最后对其他方法的调用,还可以利用将其

  • C#零基础学习理解委托

    说来惭愧,在大学的课程中,竟然没有听说过委托这个名称.那么今天我就带着大家一起探讨下委托和事件. 咱们先来看下委托 我主要从以下几个方面讲解 1,  为什么使用委托  2.什么是委托  3.委托如何使用 为什么使用委托? 委托是c#中非常重要的一个概念,使用委托使程序员可以将方法引用封装在委托对象内.然后可以将该委托对象传递给可调用所引用方法的代码,而不必在编译时知道将调用哪个方法.与C或C++中的函数指针不同,委托是面向对象,而且是类型安全的. 什么是委托? 委托是一种引用方法的类型,一旦为委

  • c#委托详解和和示例分享

    什么是委托? 委托是寻址方法的.NET版本,使用委托可以将方法作为参数进行传递.委托是一种特殊类型的对象,其特殊之处在于委托中包含的只是一个活多个方法的地址,而不是数据. 委托虽然看起来像是一种类型,但其实定义一个委托,是定义了一个新的类.下面这行代码,定义了一个委托,使用ILDasm.exe查看其生成的IL代码如图所示: 复制代码 代码如下: //定义委托,它定义了可以代表的方法的类型,但其本身却是一个类 public delegate int methodDelegate(string st

  • C#中委托的+=和-=深入研究

    写在前面 为什么会突然想说说委托?原因吗,起于一个同事的想法,昨天下班的路上一直在想这个问题,如果给委托注册多个方法,会不会都执行呢?为了一探究性,就弄了个demo研究下. += 大家都知道委托都继承自System.MulticastDelegate,而System.MulticastDelegate又继承自System.Delegate,可以通过+=为委托注册多个方法.那么他们是否都执行了呢?执行的结果又是怎样的呢?有返回值和没返回值的是否结果是否一样?那就试着说说+=都干了哪些事? 测试代码

随机推荐