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

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

先来看看下面的例子:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

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的函数,但毕竟两者属于不同的委托类型,因此,下面的代码显然是无法编译通过的:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

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>类型:


1

2

3

4

5

6

7

8

public static class Extensions

{

public static Predicate<T> ToPredicate<T> (this Func<T, bool> source)

{

Predicate<T> result = new Predicate<T>(source);

return result;

}

}

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


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

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#程序设计有所帮助。

时间: 2024-10-12 21:46:51

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

(转)C#中的Predicate&lt;T&gt;与Func&lt;T, bool&gt;

Delegate至少0个参数,至多32个参数,可以无返回值,也可以指定返回值类型.这个是祖宗.  Func可以接受0个至16个传入参数,必须具有返回值.  Action可以接受0个至16个传入参数,无返回值.  Predicate只能接受一个传入参数,返回值为bool类型. public delegate bool Predicate<in T>(T obj); public delegate TResult Func<in T, out TResult>(T arg); Func

Func&lt;T,TResult&gt;泛型委托

描述: 封装一个具有一个参数并返回TResult参数指定的类型值的方法. 语法: public delegate TResult Func<T,TResult>(T arg); 参数类型: T:此委托封装的方法的参数类型. TResult:此委托封装的方法的返回值类型. 参数: arg:委托封装的方法的参数 返回值:此委托封装的方法的返回值 备注: 可以使用此委托构造一个能以参数形式传递的方法,而不用显式声明自定义的委托.该方法必须与此委托的方法签名想对应. 也就是说,封装的方法必须具有一个通

SQL中拆分字符串substr及统计字符出现频数replace用法实例讲解

一.拆分字符串为若干行 例一:要求将表emp中的'king'按照每行一个单词拆成四行 注意:substr(str,pos):截取pos位置开始的字符: substr(str,pos,len):从pos位置开始,选出接下去的len个字符 表emp: eid ename 1 ring 2 king 3 ting 4 ping 首先,建立表tmp(基干表,为了配合表一使用): tid 1 2 3 4 5 然后,select emp.ename,tmp.tid from emp,tmp where em

Func&lt;T, bool&gt;与Expression&lt;Func&lt;T, bool&gt;&gt;的区别

Func<T, bool>是委托(delegate) Expression<Func<T, bool>>是表达式 Expression编译后就会变成delegate,才能运行.比如 Expression<Func<int, bool>> ex = x=>x < 100; // 将表达式树描述的 lambda 表达式编译为可执行代码,并生成表示该 lambda 表达式的委托. Func<int, bool> func = e

Expression&lt;Func&lt;TObject, bool&gt;&gt;与Func&lt;TObject, bool&gt;的区别

Func<TObject, bool>是委托(delegate) Expression<Func<TObject, bool>>是表达式 Expression编译后就会变成delegate,才能运行.比如 Expression<Func<int, bool>> ex = x=>x < 100; Func<int, bool> func = ex.Compile(); 然后你就可以调用func: func(5) //-返回

lambda表达式Expression&lt;Func&lt;Person, bool&gt;&gt; 、Func&lt;Person, bool&gt;区别

前言: 自己通过lambda表达式的封装,将对应的表达式转成字符串的过程中,对lambda表达式有了新的认识 原因: 很多开发者对lambda表达式Expression<Func<Person, bool>> .Func<Person, bool>表示存在疑惑,现在就用代码举个简单列子 原代码: using System;using System.Collections.Generic;using System.Linq;using System.Linq.Expres

C#中FormsAuthentication用法实例

using System; using System.Web; using System.Web.Security; namespace AuthTest { public class Authentication { /// <summary> /// 设置用户登陆成功凭据(Cookie存储) /// </summary> /// <param name="UserName">用户名</param> /// <param name

表达式拼接Expression&lt;Func&lt;IEntityMapper, bool&gt;&gt; predicate

/// <summary> /// 重写以筛选出当前上下文的实体映射信息 /// </summary> protected override IEnumerable<IEntityMapper> EntityMappersFilter(IEnumerable<IEntityMapper> entityMappers) { Type contextType = typeof(TDbContext); Expression<Func<IEntityM

.NET Core中合并Expression&lt;Func&lt;T,bool&gt;&gt;的正确姿势

这是在昨天的 .NET Core 迁移中遇到的问题,之前在 .NET Framework 中是这样合并 Expression<Func<T,bool>> 的: public static class ExpressionBuilder { public static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second, Func<Expr