引用别人的:

  1. static void Main(string[] args)
  2. {
  3. List<string> l = new List<string>();
  4. l.Add("a");
  5. l.Add("b");
  6. l.Add("s");
  7. l.Add("t");
  8.  
  9. if (l.Exists(s => s.Equals("s")))
  10. {
  11. string str = l.First(s => s.Equals("s"));
  12. Console.WriteLine(str);
  13. }
  14. else
  15. Console.WriteLine("Not found");
  16. }

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

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

  1. static void Main(string[] args)
  2. {
  3. List<string> l = new List<string>();
  4. l.Add("a");
  5. l.Add("b");
  6. l.Add("s");
  7. l.Add("t");
  8. Func<string, bool> p = s => s.Equals("s");
  9. if (l.Exists(p))
  10. {
  11. string str = l.First(p);
  12. Console.WriteLine(str);
  13. }
  14. else
  15. Console.WriteLine("Not found");
  16. }

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

  1. public static class Extensions
  2. {
  3. public static Predicate<T> ToPredicate<T> (this Func<T, bool> source)
  4. {
  5. Predicate<T> result = new Predicate<T>(source);
  6. return result;
  7. }
  8. }

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

  1. static void Main(string[] args)
  2. {
  3. List<string> l = new List<string>();
  4. l.Add("a");
  5. l.Add("b");
  6. l.Add("s");
  7. l.Add("t");
  8. Func<string, bool> p = s => s.Equals("s");
  9. if (l.Exists(p.ToPredicate()))
  10. {
  11. string str = l.First(p);
  12. Console.WriteLine(str);
  13. }
  14. else
  15. Console.WriteLine("Not found");
  16. }

Exists不过是做判断,因此需要用断言表达式,而在做First操作的时候,则更多的意义上是在迭代地调用指定的方法。

Predicate<T>与Func<T, bool>泛型委托的更多相关文章

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

    本文以实例形式分析了C#中Predicate<T>与Func<T, bool>泛型委托的用法,分享给大家供大家参考之用.具体如下: 先来看看下面的例子: 1 2 3 4 5 6 ...

  2. (转)C#中的Predicate<T>与Func<T, bool>

    Delegate至少0个参数,至多32个参数,可以无返回值,也可以指定返回值类型.这个是祖宗.  Func可以接受0个至16个传入参数,必须具有返回值.  Action可以接受0个至16个传入参数,无 ...

  3. Func<T,TResult>泛型委托

    描述: 封装一个具有一个参数并返回TResult参数指定的类型值的方法. 语法: public delegate TResult Func<T,TResult>(T arg); 参数类型: ...

  4. Expression<Func<T, bool>>与Func<T, bool>的区别

    转自:http://www.cnblogs.com/wow-xc/articles/4952233.html Func<TObject, bool>是委托(delegate) Expres ...

  5. Expression<Func<TObject, bool>>与Func<TObject, bool>的区别

    Func<TObject, bool>是委托(delegate) Expression<Func<TObject, bool>>是表达式 Expression编译后 ...

  6. lambda表达式Expression<Func<Person, bool>> 、Func<Person, bool>区别

    前言: 自己通过lambda表达式的封装,将对应的表达式转成字符串的过程中,对lambda表达式有了新的认识 原因: 很多开发者对lambda表达式Expression<Func<Pers ...

  7. 泛型委托 Predicate/Func/Action

    Predicate 泛型委托  表示定义一组条件并确定指定对象是否符合这些条件的方法.此委托由 Array 和 List 类的几种方法使用,用于在集合中搜索元素.看看下面它的定义: // Summar ...

  8. C#的泛型委托Predicate/Func/Action(转)

    Predicate 泛型委托:表示定义一组条件并确定指定对象是否符合这些条件的方法.此委托由 Array 和 List 类的几种方法使用,用于在集合中搜索元素. 类型参数介绍:    T: 要比较的对 ...

  9. (C#) Action, Func, Predicate 等泛型委托

    (转载网络文章) (1). delegate delegate我们常用到的一种声明   Delegate至少0个参数,至多32个参数,可以无返回值,也可以指定返回值类型.   例:public del ...

随机推荐

  1. [Head First设计模式]策略模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...

  2. R中的<-和=赋值符号的细致区别

    <-创建的变量的作用范围可以在整个顶层环境,而=仅仅在一个局部环境. 但要<-创建的变量如果是在函数实参传递的时候创建的,其的作用范围可以在整个顶层环境,有一个前提条件:对应的形参在函数内 ...

  3. R语言:规划求解优化ROI

    今天看到一篇文章介绍如何用excel建模对ROI 进行规划求解. 蓝鲸的网站分析笔记 成本 Cost 每次点击费用 CPC 点击量 \[clickRate = \frac{cost}{CPC}\] 转 ...

  4. 【Go入门教程3】流程(if、goto、for、switch)和函数(多个返回值、变参、传值与传指针、defer、函数作为值/类型、Panic和Recover、main函数和init函数、import)

    这小节我们要介绍Go里面的流程控制以及函数操作. 流程控制 流程控制在编程语言中是最伟大的发明了,因为有了它,你可以通过很简单的流程描述来表达很复杂的逻辑.Go中流程控制分三大类:条件判断,循环控制和 ...

  5. Android中的动画机制

          1 逐帧动画   逐帧动画 就是一系列的图片按照一定的顺序展示的过程.   逐帧动画很简单, 只需要在drawable中或者anim中定义一个Animation-list 其中包含多个it ...

  6. 序列化对象为xml字符串

    /// <summary>    /// 序列化对象为xml字符串    /// </summary>    /// <param name="obj" ...

  7. JavaScript "自"运行-setInertval()和setTimeout()理解

    setInterval()和clearInterval() var result = "Y"; function onOk() { var tid = setInterval(fu ...

  8. 【Maven】解决缺少Jar包问题

    解决办法:进入项目的根目录(即 pom.xml文件所在的目录)执行:mvn dependency:copy-dependencies完成后进入eclipse,发现项目不再报错前提条件:1,安装了mav ...

  9. [转]Struts2工作原理

    Struts2请求响应流程: 在struts2的应用中,从用户请求到服务器返回相应响应给用户端的过程中,包含了许多组件如:Controller.ActionProxy.ActionMapping.Co ...

  10. PHP 链接数据库1(连接数据库&简单的登录注册)

    对 解析变量的理解 数据库的名称和表的名称不能重复 从结果中取出的数据   都是以数组的形式取出的 1.PHP查询数据库中的某条信息 //PHP链接数据库 /*1.造链接对象 IP地址 用户名 密码 ...