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

 更新时间:2014年09月06日 11:22:10   投稿:shichen2014  
这篇文章主要介绍了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#程序设计有所帮助

相关文章

  • unity实现UI元素跟随3D物体

    unity实现UI元素跟随3D物体

    这篇文章主要为大家详细介绍了unity实现UI元素跟随3D物体,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • 基于C#编写一个远程桌面应用

    基于C#编写一个远程桌面应用

    封闭环境无法拷贝外来的远程桌面软件,所以这篇文章小编就来带大家用C#编写一个简单的远程桌面应用,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-10-10
  • c#判断操作系统位数的示例分享

    c#判断操作系统位数的示例分享

    这篇文章主要介绍了c#判断操作系统位数的示例,在.net 4.5中,判断操作系统不用再写方法去判断了,有直接可以利用的属性了哦
    2014-01-01
  • ASP.NET总结C#中7种获取当前路径的方法

    ASP.NET总结C#中7种获取当前路径的方法

    本文主要介绍了7种获取当前路径的方法,并做了代码演示,分享给大家,感兴趣的朋友可以参考一下。
    2016-03-03
  • 快速了解如何在.NETCORE中使用Generic-Host建立主机

    快速了解如何在.NETCORE中使用Generic-Host建立主机

    这篇文章主要介绍了如何在.NETCORE中使用Generic-Host建立主机,文中代码非常详细,可供大家参考,感兴趣的朋友不妨阅读完
    2020-05-05
  • C#生成设置范围内的Double类型随机数的方法

    C#生成设置范围内的Double类型随机数的方法

    这篇文章主要介绍了C#生成设置范围内的Double类型随机数的方法,对于C#的初学者有很好的借鉴价值,需要的朋友可以参考下
    2014-08-08
  • 基于C#制作一个休息提醒闹钟的详细步骤

    基于C#制作一个休息提醒闹钟的详细步骤

    小闹钟大家都应该很熟悉,它包括时间、事件,当达到某某时间时,事件发生了,并且还有一个提示信息,下面这篇文章主要给大家介绍了关于如何基于C#制作一个休息提醒闹钟的详细步骤,需要的朋友可以参考下
    2023-02-02
  • c# ArrayList的使用方法小总结

    c# ArrayList的使用方法小总结

    arraylist是接口list的实现类,所以在使用过程中比较推荐使用list接口来实现,arraylist在程序开发过程中应用非常广泛,接下来,脚本之家的小编给大家总结了arraylist的使用,有需要的朋友可以参考下
    2015-09-09
  • C#实现电子邮件发送功能(支持普通文本,HTML和附件)

    C#实现电子邮件发送功能(支持普通文本,HTML和附件)

    在日常开发或自动化任务中,发送电子邮件仍然是最常用的数据传递方式之一,本文我们就来讲讲如何使用 C# 发送包含普通文本,HTML 正文以及附件的电子邮件吧
    2025-07-07
  • C#使用Npoi实现生成Word文档

    C#使用Npoi实现生成Word文档

    这篇文章主要为大家详细介绍了C#如何使用Npoi实现生成Word文档,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下
    2024-03-03

最新评论