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

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

一、自定义委托类型

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 == )
{
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}", , , method(, ));
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=", "");
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 > ; }; Console.WriteLine(method());// 输出:True
Console.ReadKey();
}
}
}

三、综合应用

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

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace 运用
{
class Program
{
static void Main(string[] args)
{
List<Student> list = new List<Student>
{
new Student{Name="张三",Age=},
new Student{Name="李四",Age=},
new Student{Name="王五",Age=},
new Student{Name="马六",Age=},
new Student{Name="李七",Age=}
}; // Func委托类型
List<Student> list2 = list.Where(item => item.Age < ).ToList();
foreach (Student stu in list2)
{
Console.WriteLine("姓名:{0},年龄:{1}。", stu.Name, stu.Age);
}
Console.WriteLine("============================"); // Action委托类型
list.ForEach((s) => { Console.WriteLine("姓名:{0},年龄:{1}。", s.Name, s.Age); });
Console.WriteLine("============================"); // Predicate委托类型
Student student = list.Find(item => item.Age > );
Console.WriteLine("姓名:{0},年龄:{1}。", student.Name, student.Age);
Console.WriteLine("============================"); Console.ReadKey();
}
} class Student
{
public string Name { get; set; } public int Age { get; set; }
}
}

运行结果:

.Net自带的委托类型—Func,Action 和 Predicate的更多相关文章

  1. C#内置委托类型Func和Action对比及用法

    C#的内置委托类型 Func Action 返回值 有(只有一个Tresult) 无 重载 17个(0参-16参) 17个(0参-16参) 泛型 支持 支持 系统内置 是 是 是否需要声明 否 否 c ...

  2. 自定义委托类型 - .Net自带委托类型

    委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递. 与其他的类不同,委托类具有一个签名,并且它只能对与其签名匹配的方法进行引用. 一.自定义委托类型 1.语法结构:访问修 ...

  3. C#委托Action、Action<T>、Func<T>、Predicate<T>系统自带的委托

    C#委托Action.Action<T>.Func<T>.Predicate<T>   CLR环境中给我们内置了几个常用委托Action. Action<T& ...

  4. 通过IL分析C#中的委托、事件、Func、Action、Predicate之间的区别与联系

    先说一下个人理解的结论吧: delegate是C#中的一种类型,它实际上是一个能够持有对某个方法的引用的类. delegate声明的变量与delegate声明的事件,并没有本质的区别,事件是在dele ...

  5. 浅谈C#中常见的委托<Func,Action,Predicate>(转)

    一提到委托,浮现在我们脑海中的大概是听的最多的就是类似C++的函数指针吧,呵呵,至少我的第一个反应是这样的. 关于委托的定义和使用,已经有诸多的人讲解过,并且讲解细致入微,尤其是张子阳的那一篇.我就不 ...

  6. .NET自带泛型委托方法Func、Action和Predicate

    Func.Action和Predicate是.NET自带的3个泛型委托方法,三个方法的区别其实并不大,要强行给混着用也是可以的,但是我们是有追求的人,把道理讲清楚总是好的. 一.Func是有返回值的方 ...

  7. C# delegate event func action 匿名方法 lambda表达式

    delegate event action func 匿名方法 lambda表达式 delegate类似c++的函数指针,但是是类型安全的,可以指向多个函数, public delegate void ...

  8. C# Task中的Func, Action, Async与Await的使用

    在说Asnc和Await之前,先说明一下Func和Action委托, Task任务的基础的用法 1. Func Func是一种委托,这是在3.5里面新增的,2.0里面我们使用委托是用Delegate, ...

  9. C#委托Action、Action<T>、Func<T>、Predicate<T>

    CLR环境中给我们内置了几个常用委托Action. Action<T>.Func<T>.Predicate<T>,一般我们要用到委托的时候,尽量不要自己再定义一 个 ...

随机推荐

  1. Cron和Spring定时任务

    1.Java Spring spring定时任务cronExpression的值(配置定时时间)格式说明: 一个cronExpression表达式有至少6个(也可能是7个)由空格分隔的时间元素.从左至 ...

  2. windows下 apache 二级域名相关配置

    小编今天给大家总结下 windows 下 apache的二级域名的相关配置 利用.htaccess将域名绑定到子目录 下面就利用本地127.0.0.1进行测试 我们这里以 www.jobs.com 为 ...

  3. LaTeX让公式跟随章节编号

    正常公式编号会是(1)(2)这种,想要编号成(3.1) (3.2)怎么办呢? \usepackage{amsmath} \numberwithin{equation}{section} 在导言区加入以 ...

  4. PHP 学习笔记 01

    例子: 为什么要学PHP 主观原因: 前段时间在学校处理了毕业的一些事情,回到上海后开始了找工作的旅程.意向工作是WPF开发或者ASP.NET 作为后端的WEB开发. 陆陆续续一直在面试,其中有一家公 ...

  5. printf输出格式总结

    printf函数称为格式输出函数,其关键字最末一个字母f即为"格式"(format)之意.其功能是按用户指定的格式,把指定的数据显示到显示器屏幕上. printf函数调用的一般形式 ...

  6. Cygwin ssh服务配置 (SecureCRT连接Cygwin配置)

    1.运行ssh-host-config 这里需要注意的是标红部分,输入的用户名或密码要符合计算机的用户名或密码策略(尤其是公司有权限限制的电脑). $ ssh-host-config *** Quer ...

  7. windows32位下安装mongodb

    下载mongodb:http://downloads.mongodb.org/win32/mongodb-win32-i386-2.4.5.zip 给mongodb指定一个数据存放路径:这里我们放在m ...

  8. Effiective C++ (一)

    最近在看Effective  C++ ,同时将总结一下里边的重要知识点: ##########################    module  1    #################### ...

  9. Android greenDao的简单配置和使用

    最近自学做东西的时候用到了一个收藏的功能,然后我想把东西存放到SQLite当中,然而自己传值的时候都是用到的实体类,所以存起来也比较麻烦,所以从网上找到一个greenDao的开源框架非常火,不仅效率高 ...

  10. django-south

    python manage.py schemamigration youappname --initial # --initial在数据库创建models定义的表,以及South需要的south_mi ...