隐藏

【C#】Action,Func,Predicate的简单使用

发布:2019/10/15 23:38:40作者:管理员 来源:本站 浏览次数:945

Action和Func

 

相同点

    都是delegate
    都是泛型委托
    都是最多有16个参数

不同点

    Action 无返回值,Func 有一个返回值

 

还有一个系统定义的委托Predicate,不常用,只能传一个参数并返回一个bool类型的值

 

Action和Func就是系统定义好的委托,其实我们也可以自己定义,但是如果每次使用都自己定义也太麻烦了,所以还是使用现成的

 
Action

无返回值

Action<int, int> action = new Action<int, int>(Add);

定义一个Action,参数为两个int类型参数的方法

    private static void Add(int a, int b)
    {
        Console.WriteLine("{0} + {1} = {2}", a, b, a + b);
    }

 
Func

有一个返回值

Func<int, int, int> func = new Func<int, int, int>(Add2);

前面两个int对应着Add2方法参数的a和b,第三个int为返回值

    private static int Add2(int a, int b)
    {
        return a + b;
    }

 
Predicate

传一个参数并返回一个bool类型的值

Predicate<bool> predicate = new Predicate<bool>(isEqual);

 

    private static bool isEqual(bool b)
    {
        return b;
    }

 
结合 Lambda 表达式

Action

Action<int, int> action = (a, b) => { Console.WriteLine("{0} + {1} = {2}", a, b, a + b); };

当语句块只有一条语句时,可以进一步简写成

 Action<int, int> action = (a, b) => Console.WriteLine("{0} + {1} = {2}", a, b, a + b);

Func

Func<int, int, int> func = (a, b) => { return a + b; };

进一步简写

Func<int, int, int> func = (a, b) => a + b;

Predicate

Predicate<bool> predicate = (b) => { return b; };

进一步简写

Predicate<bool> predicate = (b) => b;

 
用作方法的参数

通常方法的参数都是一些常用的数据类型,比如int,string,bool等

如果我们想将一个语句块作为参数,使用普通的数据类型作为参数就行不通了,这时候可以用到委托了

 
一个简单的例子

定义一个两个数相加的方法,但是这两个数都是通过不同的运算方法得到的

    private static int Add(Func<int> reslut1, Func<int> reslut2)
    {
        int num1 = reslut1();
     
        int num2 = reslut2();
     
        int sum = num1 + num2;
     
        return sum;
    }

运用

这个运算过程可能是更复杂的过程

    int a = 2, b = 3;
     
    Add(() =>
    {
        int sub = a - b;
        return sub;
    }, () =>
    {
        int nul = a * b;
        return nul;
    });

 

这个例子可能不太形象,举个更实用的例子

 
一个复杂一点的例子

如,现在执行一个发指令的方法,即上位机软件发送指令到下位机,由于经常发指令,所以把执行指令的方法写成一个模板方法

发指令的过程;
1.从数据库获取指令
2.对指令的参数进行赋值
3.执行指令(其中执行指令又分为发送与等待结果等)
4.对执行指令的结果进行解析


现在,用一个简单的例子模拟发指令的过程

先建立两个Model,一个存放指令,一个存放指令运行结果

    /// <summary>
    /// 指令
    /// </summary>
    public class Instruction
    {
        /// <summary>
        /// 名称
        /// </summary>
        public string Name;
        /// <summary>
        /// 指令编号
        /// </summary>
        public int CurNo;
        /// <summary>
        /// 参数
        /// </summary>
        public byte[] Param;
    }
     
     
    /// <summary>
    /// 指令执行详细信息
    /// </summary>
    public class OperateDetail
    {
        /// <summary>
        /// 参数
        /// </summary>
        public byte[] Param;
    }

执行指令的模板方法

    public static bool ExecuteTemplet(Func<Instruction> Ins, out OperateDetail reslut)
    {
        reslut = new OperateDetail();
     
        Instruction model = Ins();
     
        //执行指令(省略) 将指令model发送到下位机
        //返回结果(省略) 从是数据库中查询结果赋值给reslut
     
        return true;
    }

 

模板方法写好了,

现在需要获取设置序列号,写一个设置序列号的方法,

其中调用模板方法,这样可以不用重复写执行指令和返回结果的方法

    public static bool SetSN(string sn)
    {
        sn = string.Empty;
        bool bExecute = ExecuteTemplet(() =>
        {
            Instruction ins = new Instruction();
     
            //从数据库中获取指令(省略)
     
            //对指令参数进行赋值
            ins.Param = Encoding.Default.GetBytes(sn);
     
            ins.CurNo = 1;
     
            return ins;
        }, out OperateDetail reslut);
     
        if (bExecute == false)
        {
            return false;
        }
     
        return true;
    }

现在有来一个方法,获取序列号

    public static bool GetSN(out string sn)
    {
        sn = string.Empty;
        bool bExecute = ExecuteTemplet(() =>
        {
            Instruction ins = new Instruction();
     
            //从数据库中获取指令(省略)
     
            //对指令参数进行赋值
            ins.CurNo = 1;
     
            return ins;
        }, out OperateDetail reslut);
     
        if (bExecute == false)
        {
            return false;
        }
        //解析结果
        sn = Encoding.Default.GetString(reslut.Param);
     
        return true;
    }

由这个两个方法,可以看出,利用Func作为方法的参数,可以定义模板方法,不用重复同样的代码,后期维护也简单
————————————————
版权声明:本文为CSDN博主「GreAmbWang」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_38211198/article/details/94126112