浅谈C#中常见的委托<Func,Action,Predicate>

前言:

一提到委托,浮现在我们脑海中的大概是听的最多的就是类似C++的函数指针吧,呵呵,至少我的第一个反应是这样的。

Func是一种委托,这是在3.5里面新增的,2.0里面我们使用委托是用Delegate,Func位于System.Core命名空间下,使用委托可以提升效率,例如在反射中使用就可以弥补反射所损失的性能。

委托是面向对象的编程语言中新加入的一种特性,在C#中引入委托使得C#程序的编写更加灵活。
C#,中可以自己定义各种各样的委托,但是C#语言也预先为我们定义了两个做常用的委托,一个是Func一个是Action.

Action< T > 委托
函数最基本的特点就是输入输出,即输入参数-> 执行运算-> 输出参数,Action是一类没有输出参数的委托,但是输入参数可以为C#中的任意类型,即可以委托执行一下形式的方法。

public void f1(string str, int i)
    {
    ...
    }

该函数用Action委托就是:

Action<String, int> do_f1 = f1;

使用时候直接用

do_f1("hello", 12);

Func< T >委托
知道了Action委托,很好理解Func委托,Func委托是由返回值的委托,其中,输入参数和返回值都用泛型表示,例如以下函数的Func委托:

public string f2(int i1, int i2)
    {
        return (i1+i2).toString();
    }

其Func委托为:

Func<int ,int, string> do_f2=f2;

使用的时候直接用:

string result = do_f2(1,2);

一、说明

一般我们定义委托都是有如下两步:

public delegate void MyDelegate(string name);//定义委托
public MyDelegate myDelegate; //使用委托

但.Net也提供了定义好的委托,我们可以直接使用,比如Func和Action

二、定义

System.Action 无返回值

Action:
public delegate void Action ();

Action< T >:
public delegate void Action< T > (T obj);

Action< T1, T2 >:
public delegate void Action< T1, T2 > (T1 arg1, T2 arg2);
* delegate void Action<T1,T2,T3,T4>T1 arg1, T2 arg2, T3 arg3, T4 arg4);

System.Func 有返回值

Func< TResult >
public delegate TResult Func< TResult > ();

Func< T,TResult >
public delegate TResult Func< T, TResult > (T arg);

Func< T1,T2,TResult >
public delegate TResult Func< T1, T2, TResult > (T1 arg1, T2 arg2);
*delegate TResult Func<T1,T2,T3,T4,TResult>T1 arg1, T2 arg2, T3 arg3, T4 arg4);

Predicate只能接受一个传入参数,返回值为bool类型

 

三、示例理解

例子1:Action

using UnityEngine;
using System.Collections;
using System;
public class ActionTest : MonoBehaviour 
{
    void Start () 
    {
        Action action = XXX;
        action();
    }
    void XXX()
    {
        Debug.Log("100");
    }
}

例子2:Action<T>

using UnityEngine;
using System.Collections;
using System;
public class ActionTest : MonoBehaviour 
{
    void Start () 
    {
        Action<string> action = XXX;
        action("unity C#");
    }
    void XXX(string name)
    {
        Debug.Log(name);
    }
}

例子3:Action<T1,T2>

using UnityEngine;
using System.Collections;
using System;
public class ActionTest : MonoBehaviour 
{
    void Start () 
    {
        Action<string,int> action = XXX;
        action("unity C#",100);
    }
    void XXX(string name,int score)
    {
        Debug.Log(string.Format("{0}  {1}",name,score);
    }
}

例子4:Action  直接代理delegate函数体用法

#region Action的用法
    ///Action<T>的用法
    ///这里的T为代理函数的传入类型,无返回值
    Action<string[]> action = delegate(string[] x)
    {
        var result = from p in x
                     where p.Contains("s")
                     select p;
        foreach (string s in result.ToList())
        {
            Console.WriteLine(s);
        }
    };
    string[] str={ "charlies","nancy","alex","jimmy","selina"};
    action(str);
    Console.ReadKey();
#endregion
上面的例子是通过传入的String类型的数组,找出其中包含有字符s的项,然后输出到控制台。

例子5:Func<TResult >

using UnityEngine;
using System.Collections;
using System;
public class FuncTest : MonoBehaviour 
{
    void Start () 
    {
        Func< int > func= XXX;
       Debug.Log( func() );
    }
    int XXX()
    {
        return 10;
    }
}

例子6: Func<T,TResult>

using UnityEngine;
using System;

public Class FuncTest:MonoBehaviour
{
   void Start()
     {
       Func<string ,int> func= CallStringLength;
     }

    int CallStringLength(string str)
     {
         return str.Lenth;
     }

}

例子7: Func<TResult> 直接使用代理delegate函数体

Func<string> func=delegate()
{
    return "我是Func<TResult>委托返回的结果";
}
 

例子8:Predicate只能接受一个传入参数,返回值为bool类型,直接使用代理delegate函数体

#region Predicate
  ///bool Predicate<T>的用法
    ///输入一个T类型的参数,返回值为bool类型
    Predicate<string[]> predicate = delegate(string[] x)
    {
        var result = from p in x
                     where p.Contains("s")
                     select p;
        if (result.ToList().Count > 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    };
    string[] _value = { "charlies", "nancy", "alex", "jimmy", "selina" };
    if (predicate(_value))
    {
        Console.WriteLine("They contain.");
    }
    else
    {
        Console.WriteLine("They don't contain.");
    }
    Console.ReadKey();
#endregion

上面的代码其实也是判断String数组中有没有包含s的项,有的话就在控制台打印出  They contain.没有的话就打印出They don't contain

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值