C#中匿名函数、委托delegate和Action、Func、Expression、还有Lambda的关系和区别
以前一直迷迷糊糊的,现在总算搞明白。
Lambda表达式
Lamda表达式基本写法是()=>{ };
Lambda和方法一样都可以传入参数和拥有返回值。(int x)=>{return x;};
Lambda表达式并不是C#独有的,其它语言也拥有Lambda表达式。
一些文档上写Lambda是匿名函数,我认为是不对的,Lambda可以表示一个匿名函数,但是还可以来表示Linq表达式啊。
delegate委托
委托基本的使用包括声明一个委托、实例化一个委托、使用一个委托。
// 声明一个委托,类型是myDelegate,
public delegate void myDelegate(string str);
public static void HellowChinese(string strChinese)
{
Console.WriteLine("Good morning," + strChinese);
Console.ReadLine();
}
// 实例化
myDelegate d = new myDelegate(HellowChinese);
// 使用
d("Mr wang");
委托很好用。当编程到一定阶段,发现只传递一个或几个int、strig类型参数是不够的,希望可以把一段代码进行传递来执行某个操作,委托提供了这样的途径,委托提供了一种可以直接访问类中方法的途径,可以将方法当作一个参数传递从而使用。
匿名函数
上面已经讲到匿名函数了。函数和方法等价,用来封装一段代码片以便随时使用,有的有返回值有的无返回值。写在类里面。
但是如果我只想把这段代码片使用一次呢?再声明一个类、一个方法实在太麻烦,这时候匿名函数就拥有了价值。用来封装一段代码、直接执行或者传递。
匿名函数总是和委托一齐使用,因为匿名函数方便了委托的使用(不用声明一个类了)
匿名方法两种实现方式:
使用Lambda表达式:
public delegate void Seep();
static void Main(string[] args)
{ Seep s = () => { Console.WriteLine(); Console.WriteLine(); };
}
使用委托
public delegate void Seep();
static void Main(string[] args)
{
Seep see = delegate () { Console.WriteLine(); };
}
Action、Func、Predicate
委托需要先声明一个类型才能使用,这很麻烦,比如我在某一个命名空间声明了一个没有返回值的委托myDelegate,然后想要这个委托的时候,每个命名空间都要引用这个命名空间,这太不友好了。
微软直接就在框架中定义了三种委托:Action、Func、Predicate。这三种委托是C#的System命名空间中已经定义好的,如Action
上面已经通过匿名函数实现了不用声明类,现在通过C#预定义的委托类型实现了不用声明委托类型,那么现在就可以直接写代码片来执行了
这三种委托的相应泛型形式,可以写出如下代码:
#region 无参数无返回值
// lambda实现委托实例
Action a1 = () => Console.WriteLine();
a1();
// delegate实现委托实例,下面不再演示delegate。
Action a2 = delegate { Console.WriteLine(); };
a2();
#endregion #region 有参数无返回值
Action<int> a3 = (x) => Console.WriteLine(x);
a3();
#endregion #region 无参数有返回值的情况
Func<int> e1= ()=> ;
var value1= e1();
#endregion #region 有参数有返回值的情况
// 最后一个泛型是返回值的类型
Func<int,int> e2 = (x) => x+;
int value2= e2();
// 多参数情况
Func<int, int,int> e3 = (x,x2) => x+x2 + ;
int value3 = e3(,);
#endregion #region 返回值是布尔类型
// 其实Predicate可以用Func返回值是bool来代替的。
Predicate<int> p = (x) => x > ;
bool value4 = p();
#endregion
委托还有一些特性(如可加性),感兴趣的可以查阅相关资料。
Expression
Expression指的是System.Linq.Expressions,是Linq表达式,表达式树,不是Lambda表达式!!
Linq表达式用于离线集合的查询。什么是离线集合?最常用的是EF里面的DBContext,我也只用过这个,所以我不想那么多,就把Expression当成EF里面使用的就行了。
1、只能接受Lambda表达式表示的委托
2、Lambda表达式只能有一条语句。
Expression<Func<int,int>> eeee = (x)=> x+ ;
总结
1、都是希望可以单独引用一段代码片引起的。
2、然后引用了委托delegate,delegate的使用方式为声明类型-实例化类型(传入想要使用的类的方法)-使用委托(使用方法)
3、简化操作,使用(通过Lambda或者delegate)匿名方法来直接声明一段代码片,避免声明所想使用的类的方法
4、简化操作,直接使用C#预定义的三种委托Action、Func、Predicate,连声明委托都省了。
5、本文代码:https://github.com/Beiluola/delegateDemo
注意
1、匿名函数总是和委托一起使用(三种预定义委托)
2、使用三种预定义委托就可以满足大多数需求。
3、Expression是Linq表达式树,只能使用接受一句lambda表达式。和匿名函数无关。
C#中匿名函数、委托delegate和Action、Func、Expression、还有Lambda的关系和区别的更多相关文章
- .net中的各种委托(Delegate、Action、Func)
1.Delegate,委托的鼻祖 protected delegate int ClassDelegate(int x, int y);//定义委托类型及参数 static void Main(str ...
- c#中匿名函数lamb表达式
c#中匿名函数lamb表达式 实例一:(其实,这样都是些语法糖) using System; using System.Collections.Generic; using System.Linq; ...
- Python中匿名函数与内置高阶函数详解
大家好,从今天起早起Python将持续更新由小甜同学从 初学者的角度 学习Python的笔记,其特点就是全文大多由 新手易理解 的 代码与注释及动态演示 .刚入门的读者千万不要错过! 很多人学习pyt ...
- C#基础知识六之委托(delegate、Action、Func、predicate)
1. 什么是委托 官方解释 委托是定义方法签名的类型,当实例化委托时,您可以将其实例化与任何具有兼容签名的方法想关联,可以通过委托实例调用方法. 个人理解 委托通俗一点说就是把一件事情交给别人来帮助完 ...
- 转载 C#匿名函数 委托和Lambda表达式
转载原出处: http://blog.csdn.net/honantic/article/details/46331875 匿名函数 匿名函数(Anonymous Function)是表示“内联”方法 ...
- C#委托delegate、Action、Func、predicate 对比用法
委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递.事件是一种特殊的委托. 一.委托的声明 (1) delegate delegate我们常用到的一种声明 Delega ...
- js中匿名函数和回调函数
匿名函数: 通过这种方式定义的函数:(没有名字的函数) 作用:当它不被赋值给变量单独使用的时候 1.将匿名函数作为参数传递给其他函数 2.定义某个匿名函数来执行某些一次性任务 var f = func ...
- C#常见委托のdelegate定义,Func,Action,Predicate总结
委托,顾名思义,就是让其他代理,本质就是为具有共性方法组定义一个方法模板:(交流可以加qq群:435226676) 委托常见的方式有一般委托显示定义,Func<T,TResult> (T, ...
- JS中匿名函数$(function(){ })和(function(){})()的区别
“$(function(){ });” Jquery语法的匿名函数,用于存放操作DOM对象的代码,执行其中代码时DOM对象已存在: (通过这样就可以在页面加载完成时通过ajax再异步加载一些数据) “ ...
随机推荐
- krpano之小地图
效果: 点击地图按钮时,小地图移入,再次点击时移出. 地图上显示表示场景位置的坐标点,和可控制场景观看方向的雷达区. 插件: radar.js(plugins) radar.swf(plugins) ...
- **不使用tuple函数,将列表转为元组
使用动态参数: l = [1, 1, 3, 4, 5] def f(*args): return args x = f(*l) print(x)
- t讯src的一点小秘密
1.腾讯网首页发表评论未做限制 风险url:http://coral.qq.com/2774166934 使用burp的intruder模块生成payload 未做任何限制导致可批量提交大量的评论…… ...
- MySQL group_concat_max_len
MySQL提供的group_concat函数可以拼接某个字段值成字符串,如 select group_concat(user_name) from sys_user,默认的分隔符是 逗号,即" ...
- python:窗口化和制作图形
#圆 from tkinter import * canvas = Canvas(width=800, height=600, bg='yellow')#声明窗口属性 canvas.pack(expa ...
- 3DMAX 处理反面
问题起源:从3DMAX导出一个模型为FBX后,在U3D中看到模型很奇怪的透视了,能看到背面看不到正面,这不法线问题,而是面反了. 即然是面反了,为什么在MAX中看起来是正确的呢? 应该是开启了双面模式 ...
- CodeFirst(反射+特性)
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Sy ...
- 使用myeclipse开发java,解决java中继承JFrame类出现The type JFrame is not accessible due to restriction的问题
在java中创建窗体,导入了java中的JFrame类,之后会出现错误: Access restriction: The type QName is not accessible due to res ...
- 201671010140. 2016-2017-2 《Java程序设计》java学习第十六周
java学习第十六周-并发 本周,学习了Java中线程,并发的知识,在老师的带领下,进行了对知识的理解学习,以及对实验的运行讲解,对这一块内容掌握的还可以,在自主编程中,也能够完成.线, ...
- easyui容易被忽略掉的部分
官方文档有这么一段话: Each component of easyui has properties, methods and events. Users can extend them easil ...