.Net自带的委托类型—Func,Action 和 Predicate

来源:互联网 发布:我的世界0.15.7坐标js 编辑:程序博客网 时间:2024/06/12 01:27

转载 http://www.cnblogs.com/shaomenghao/p/3364243.html


委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递。

与其他的类不同,委托类具有一个签名,并且它只能对与其签名匹配的方法进行引用。

一、自定义委托类型

1.语法结构:访问修饰符 delegate 返回类型 委托类型名称(参数列表);

例如:

// 声明一个委托类型,两个参数均为int类型,返回值为int类型public delegate int Calc(int a, int b);

自定义的委托可以不带参数,也可以没有返回值。

 

接下来我们看一个例子怎么使用委托

复制代码
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace 委托{    class Program    {        // 声明一个委托类型,两个参数均为int类型,返回值为int类型        public delegate int Calc(int a, int b);        // 定义和委托签名一致的方法(参数类型和个数,返回值类型均一致)        static int Add(int a, int b)        {            return a + b;        }        static int Sub(int a, int b)        {            return a - b;        }        static int Multi(int a, int b)        {            return a * b;        }        static int Divis(int a, int b)        {            if (b == 0)            {                throw new Exception("除数不能为0!");            }            return a / b;        }        static void Main(string[] args)        {            Console.WriteLine("请输入第一个数:");            int a = int.Parse(Console.ReadLine());            Console.WriteLine("请输入第二个数:");            int b = int.Parse(Console.ReadLine());            // 定义一个Calc委托类型的变量,把和该委托签名一致的Add方法的引用赋值给变量            Calc method = Add;            Console.WriteLine("加法运算:{0}+{1}={2}", a, b, method(a, b));            method = Sub;            Console.WriteLine("减法法运算:{0}-{1}={2}", a, b, method(a, b));            method = Multi;            Console.WriteLine("乘法运算:{0}×{1}={2}", a, b, method(a, b));            method = Divis;            Console.WriteLine("除法运算:{0}÷{1}={2}", a, b, method(a, b));            Console.ReadKey();        }    }}
复制代码


2.匿名方法

给上述委托变量赋值时,必须先定义好一个和委托签名一致的方法。使用匿名方法,你就无需先定义好那些方法,直接通过delegate语法给委托变量赋值。

匿名方法的结构:delegate(参数列表){函数体};

例如:

Calc method = delegate(int x, int y)            {                return x + y;            };


使用匿名方法重新实现上述例子:

复制代码
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace 匿名方法{    class Program    {        // 声明一个委托类型,两个参数均为int类型,返回值为int类型        delegate int Calc(int a, int b);        static void Main(string[] args)        {            Console.WriteLine("请输入第一个数:");            int a = int.Parse(Console.ReadLine());            Console.WriteLine("请输入第二个数:");            int b = int.Parse(Console.ReadLine());            // 定义一个Calc委托类型的变量            Calc method = delegate(int x, int y)            {                return x + y;            };            Console.WriteLine("加法运算:{0}+{1}={2}", a, b, method(a, b));            method = delegate(int x, int y)            {                return x - y;            };            Console.WriteLine("减法法运算:{0}-{1}={2}", a, b, method(a, b));            method = delegate(int x, int y)            {                return x * y;            };            Console.WriteLine("乘法运算:{0}×{1}={2}", a, b, method(a, b));            method = delegate(int x, int y)            {                return x / y;            };            Console.WriteLine("除法运算:{0}÷{1}={2}", a, b, method(a, b));            Console.ReadKey();        }    }}
复制代码

反编译生成的exe文件,你会发现编译器自动帮你生成了4个与自定义委托类型签名一致的方法,并且Main方法中的匿名方法变成了Lamdba表达式的形式,如图:

 

 

3.Lamdba表达式

Lamdba表达式其实就是一种语法糖,让你更能简洁的编写代码。

其语法结构:(参数列表)=>{函数体};

用Lamdba表达式实现上述例子:

复制代码
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Lamdba表达式{    class Program    {        // 声明一个委托类型,两个参数均为int类型,返回值为int类型        delegate int Calc(int a, int b);        static void Main(string[] args)        {            Console.WriteLine("请输入第一个数:");            int a = int.Parse(Console.ReadLine());            Console.WriteLine("请输入第二个数:");            int b = int.Parse(Console.ReadLine());            // 定义一个Calc委托类型的变量            Calc method = (x, y) => { return x + y; };            Console.WriteLine("加法运算:{0}+{1}={2}", a, b, method(a, b));            method = (x, y) => x - y; // 也可以这样写            Console.WriteLine("减法法运算:{0}-{1}={2}", a, b, method(a, b));            method = (x, y) => { return x * y; };            Console.WriteLine("乘法运算:{0}×{1}={2}", a, b, method(a, b));            method = (x, y) => { return x / y; };            Console.WriteLine("除法运算:{0}÷{1}={2}", a, b, method(a, b));            Console.ReadKey();        }    }}
复制代码

你也可以反编译生成的exe文件,你会发现结果与匿名方法反编译的效果一样。

二、.Net自带的委托类型

1.Func委托类型

Func是有返回值的泛型委托,可以没有参数,但最多只有16个参数,并且必须要有返回值,不能为void类型。如图:

Func<int, int, int> // 第一,二个参数为int类型,返回值为int类型Func<string, string, bool> // 第一,二个参数string类型,返回值为bool类型Func<int, string, decimal> // 第一个参数为int类型,第二个参数为string类型,返回值为decimal类型

 

同自定义的委托类型一样,你可以为Func委托变量赋值为方法引用,匿名方法或者Lamdba表达式:

(1)方法引用

 

(2)匿名方法

 

(3)Lamdba表达式

复制代码
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Func委托类型{    class Program    {        static int Add(int a, int b)        {            return a + b;        }        static void Main(string[] args)        {            //Func<int, int, int> method = Add;            //Func<int, int, int> method = delegate(int a, int b) { return a + b; };            Func<int, int, int> method = (x, y) => { return x + y; };                        Console.WriteLine("加法运算:{0}+{1}={2}", 3, 4, method(3, 4));            Console.ReadKey();        }    }}
复制代码

2.Action委托类型
Action是没有返回值的泛型委托,可以没有参数,但最多只有16个参数,返回值为void类型。如图:

直接看例子:

复制代码
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Action委托类型{    class Program    {        static void Main(string[] args)        {            Action<string, string> method = (s1, s2) => { Console.WriteLine(s1 + s2); };                        method("1+1=", "2");            Console.ReadKey();        }    }}
复制代码

3.Predicate委托类型
Predicate是只有一个参数,且返回值为bool类型的泛型委托。

复制代码
// 摘要://     表示定义一组条件并确定指定对象是否符合这些条件的方法。//// 参数://   obj://     要按照由此委托表示的方法中定义的条件进行比较的对象。//// 类型参数://   T://     要比较的对象的类型。//// 返回结果://     如果 obj 符合由此委托表示的方法中定义的条件,则为 true;否则为 false。public delegate bool Predicate<in T>(T obj);
复制代码

 

直接看例子:

复制代码
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Predicate委托类型{    class Program    {        static void Main(string[] args)        {            Predicate<int> method = (x) => { return x > 3; };            Console.WriteLine(method(4));// 输出:True            Console.ReadKey();        }    }}
复制代码


三、综合应用

这些自带的委托类型在泛型集合中使用的比较多,如:

 

接下来再看一个综合例子:

 View Code

运行结果:

 


0 0
原创粉丝点击