文档章节

C#的泛型委托Predicate/Func/Action

donny945
 donny945
发布于 2015/02/27 11:42
字数 928
阅读 96
收藏 2
Predicate

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

类型参数介绍:

  T: 要比较的对象的类型。

  obj: 要按照由此委托表示的方法中定义的条件进行比较的对象。

  返回值:如果 obj 符合由此委托表示的方法中定义的条件,则为 true;否则为 false

 看下面代码

public class GenericDelegateDemo
{
   List<String> listString = new List<String>()
   {
       "One","Two","Three","Four","Fice","Six","Seven","Eight","Nine","Ten"
    };

    String[] arrayString = new String[] 
    {
        "One","Two","Three","Four","Fice","Six","Seven","Eight","Nine","Ten"
    };

    public String[] GetFirstStringFromArray()
    {
        return Array.FindAll(arrayString, (c) => { return c.Length <= 3; });
    }

    public List<String> GetFirstStringFromList()
    {
        return listString.FindAll((c) => { return c.Length <= 3; });
    }

    public String[] GetFirstStringFromArray_1()
    {
        return Array.FindAll(arrayString, GetString);
    }

    public List<String> GetFirstStringFromList_1()
    {
        return listString.FindAll(GetString);
    }

    private bool GetString(String str)
    {
        if (str.Length <= 3)
            return true;
        else
            return false;
    }
}

(1)首先,上面以 数组和泛型List 两个集合作为演示对象,并构建集合。

(2)接着,两者同时使用各自 所有的 FindALL方法,参见如下定义:

   Array : public T[] FindAll<T>(T[] array, Predicate<T> match);

   List:public List<T> FindAll(Predicate<T> match);

   注意的是,两处的FindAll 均采用了Predicate (泛型委托)作为参数的类型。

(3)接着,使用两者方式展现 对Predicate 的使用:

   第一种: (c) => { return c.Length <= 3; };

   第二种: GetString(String str)。

这两者在语法上明显不同,但是实际是做相同的事情,第一种是使用Lambda表达式构建的语句,关于Lambda这里不做详述,请参见笔者C#3.0特性相关文章。

补充的是你也可以这样写,

 delegate(String c){return c.Length<=3;} 作为 Predicate定义的参数

完整代码:

XX.FindAll(delegate(String c) { return c.Length <= 3; }); 

这应该称为匿名代理了。

其他使用到Predicate 有

 Array.Find , Array.FindAll , Array.Exists , Array.FindLast , Array.FindIndex .....

 List<T>.Find , List<T>.FindAll , List<T>.Exists , List<T>.FindLast , List<T>.FindIndex .....

延伸:

 除了上面提到的外,你完全可以使用Predicate 定义新的方法,来加强自己代码。

public class GenericDelegateDemo
{
    List<String> listString = new List<String>()
    {
        "One","Two","Three","Four","Fice","Six","Seven","Eight","Nine","Ten"
    };
    public String GetStringList(Predicate<String> p)
    {
        foreach(string item in listString)
        {
            if (p(item))
                return item; 
        }
        return null;
    }

    public bool ExistString()
    {
        string str = GetStringList((c) => { return c.Length <= 3 && c.Contains('S'); });
        if (str == null)
            return false;
        else
            return true;
    }
}

同样解决了上面的问题,这里罗嗦了只是为说明Predicate的用法而已。

对于Predicate的应用当然这不是什么新鲜事情,今天细细思味一番,觉得C# 真是一门优雅的语言。

以供初学者参考。

笔者本想对以下几种泛型委托一一做些介绍和总结的,在理解Predicate的过程中,发现只要理解了泛型、委托和匿名代理,

当然你晓得Lambda表达式更好,就完全可以在适当的时候灵活应用他们了。也就是说,只是定义不同的delegate而已,

一是 你可以自己定义这样的delegate,再行使用;

二是 你需要知道象Predicate、Func、Action这样的已有好的delegate是如何定义的。或者使用的时候适当查阅下MSDN即可。

如:

Func():封装一个不具有参数但却返回 TResult 参数指定的类型值的方法。

Func(T1, T2, TResult):封装一个具有两个参数并返回 TResult 参数指定的类型值的方法,没有T2就是封装一个具有参数并....。

Action() Action(T1) Action(T2) : 封装一个方法,该方法指定数量的参数(如()无参数,(T1)一个参数,以此类推)并且不返回值。这个和Func有相似处,但无返回值而已。

 提醒大家的注意的是:

 x=>x+x;

   与

  X=> {return x+x;} 是等价的。

本文转载自:

共有 人打赏支持
donny945
粉丝 9
博文 201
码字总数 33875
作品 0
海淀
程序员
私信 提问
编写高质量代码改善C#程序的157个建议[为泛型指定初始值、使用委托声明、使用Lambda替代方法和匿名方法]

前言   泛型并不是C#语言一开始就带有的特性,而是在FCL2.0之后实现的新功能。基于泛型,我们得以将类型参数化,以便更大范围地进行代码复用。同时,它减少了泛型类及泛型方法中的转型,确...

aehyok
2014/05/15
0
0
通过IL分析C#中的委托、事件、Func、Action、Predicate之间的区别与联系

本文作者:伯乐在线 -寻找"四叶草" 。未经作者许可,禁止转载! 欢迎加入伯乐在线 专栏作者。 一直以来都是对于事件与委托比较混淆,而且不太会用。找了个时间,总结了一下,感觉清晰了很多。...

伯乐在线
2016/04/06
0
0
lambda表达式之进化

原文出处:xpy0928 前言 在C#我们可以自定义委托,但是C#为什么还要内置泛型委托呢?因为我们常常要使用委托,如果系统内置了一些你可能会用到的委托,那么就省去了定义委托,然后实例化委托...

xpy0928
2016/06/23
0
0
C#高效编程话题集2(每期10话题)

1:确保集合的线程安全 如果使用.net4.0,有新的线程安全集合类 新的 System.Collections.Concurrent 命名空间引入了多个新的线程安全集合类,可在需要时随时提供对项的无锁访问,并在锁适用...

Matrix4X4
2012/03/03
72
0
由浅到深讲解C#-LINQ

在说LINQ之前必须先说说几个重要的C#语言特性 一:与LINQ有关的语言特性   1.隐式类型     (1)源起       在隐式类型出现之前,       我们在声明一个变量的时候,    ...

天才小龙
01/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Apache用户认证,域名跳转

11月15日任务 11.18 Apache用户认证 11.19/11.20 域名跳转 11.21 Apache访问日志 11.18 Apache用户认证 vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf //把123.com那个虚拟主机编辑......

zgxlinux
37分钟前
1
0
idea 添加 VUE 的语法支持和开发

《一》VUE的开发分两种,一种是直接在HTML文件中使用,一种是VUE文件的形式开发 1,首先我们先让 HTML 文件支持 VUE 的语法指令提示 2,File -> Setting -> Edit -> Inspections -> html 3,...

文文1
55分钟前
1
0
【NLP】【七】fasttext源码解析

【一】关于fasttext fasttext是Facebook开源的一个工具包,用于词向量训练和文本分类。该工具包使用C++11编写,全部使用C++11 STL(这里主要是thread库),不依赖任何第三方库。具体使用方法...

muqiusangyang
今天
3
0
防止Tweak

什么是tweak? 英文意思为捏, 拧,扭,稍稍调整(机器、系统等)。 依据维基百科的定义,tweak指的是对电子系统进行轻微调整来增强其功能的工具;在ios中tweak特指那些能够增强其它可执行程...

HeroHY
今天
3
0
linux中常用标识---不定期更新

LINUX常用标识符: 1 & && | || &: 表示进程在后台运行 例如 redis-server & 不是所有后台运行都是& 比如es ./bin/elasticsearch -d es后台运行&&: 第一个命令执行成功后 才执行后面的命令...

geek土拨鼠
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部