委托,lambda表达式和事件
来源:互联网 发布:php开发教程视频 编辑:程序博客网 时间:2024/06/04 17:43
要区分三者之间的联系与区别首先要明白它们的定义
什么是委托?
委托是类型安全的类,它定义了返回类型和参数类型。委托由关键字delegate来声明
什么情况使用委托?
当要把方法传送给其他方法是,需要使用委托。
既然委托是将方法作为参数传递它,那么委托与指针有什么联系?
委托是面向对象,是类型安全的。
在C++中,函数指针只不过是一个指向内存位置的指针,它不是类型安全的。
委托包含:普通委托,lambda表达式和匿名方法,事件
一、普通委托(单路委托,多播委托,泛型委托(Action<T>和Func<T>))
定义一个委托类的语法:
[访问限制符] delegate [返回值类型] [委托类的名称]( [参数列表] );
1.单路委托(单路委托就是和方法建立一对一的关系)2.多播委托(多播委托就是和方法建立一对多的关系)
3.泛型委托
泛型Action<T>委托类表示引用一个void返回类型的方法
Func<T>委托的使用方式和Action<T>委托类似.Func<T>允许调用带有返回值的方法
二、匿名方法和lambda表达式
1.匿名方法(是用作委托的参数的一段代码)
用匿名方法定义委托的语法与前面的定义没有区别,但在实例化委托时有所区别,如下实例说明了如何使用匿名方法
static void Main()
{
string mid=",middle part,";
Func<string,string> anonDel=delegate(string param)
{
param +=mid;
param +="and this was added to the string.";
return param;
};//结尾的";"别忘记
Console.WriteLine(anonDel("Start of string"));
}
/*使用匿名委托的时,要遵守两个原则:
1、匿名方法中不能有跳转语句(break, goto或continue)跳转到匿名方法的外部,反之,外部代码也不能跳转到该匿名方法内部。
2、在匿名方法中不能访问不安全代码。
注意:不能访问在匿名方法外部使用的ref和out参数。*/
2.Lambda表达式(只要有委托参数类型的地方,就可以使用Lambda表达式)
语法:
[委托类] [委托对象名] = ( [参数列表] ) => { /*代码块*/ }; //结尾还是有一个分号将前面使用匿名方法的例子改为lambda表达式:
static void Main()
{
string mid=",middle part,";
Func<string,string> lambda=param=>
{
param +=mid;
param +="and this was added to the string.";
return param;
};//结尾的";"别忘记
Console.WriteLine(lambda("Start of string"));
}
三、事件
事件基于委托,为委托提供了一种发布/订阅机制。事件是一种特殊多播委托,换句话来说,事件是经过深度封装的委托。一个事件简单的可以看作一个多播委托加上两个方法(+=订阅消息和-=取消订阅)。
1、普通事件
我们使用event关键字来声明事件,语法如下:[访问权限修饰符] event [委托类类名] [名称];
事件一般是用于通知代码发生了什么。由此我们又可以引出两个概念:1、事件发布方2、事件侦听方。我们现在用一个简单的例子来说明这两个概念,我们以烧开水为例,当水温为95至100度时发出警报。我们先来定义在事件发生时,需要传输的数据成员:
public class Water//事件发布程序中的基本数据成员类{ public int Temperature { get; private set; } public Water(int t) { this.Temperature = t; }}
有了传输的数据,那么我们现在就可以定义事件触发类::
public delegate void WaterHandler(object sender, Water w); //sender为事件发送者,w为发送的数据public class Heater//事件发布程序中的,事件触发类{ public event WaterHandler WaterEvent; //深度的封装委托 public void HeatWater()//该方法用于触发事件 { for (int i = 0; i < 101; i++) { if (i > 95 && i < 101) { RegWaterEvent(i);//触发事件 } } } protected virtual void RegWaterEvent(int t) { WaterHandler temp = WaterEvent; if (temp != null) temp(this, new Water(t));//如果委托不为空,我们就执行委托,我们无需知道具体执行了哪些方法 }}
现在我们已经完整了定义好了事件发布方了,通过这个例子我们也知道了事件发布方由两部分组成:1、基本数据类 2、事件触发类。接下来我们继续看看事件侦听方又是怎么样的:
public class Alarm//事件侦听类{ public void Waring(object sender, Water w)//侦听接口,由于侦听事件的发布 { Console.WriteLine("当前水温已经到达 {0} ℃!", w.Temperature); }}
通过这个例子我们可以发现,事件侦听类,只需有一个和被监听事件一致的方法即可。
Heater heater = new Heater();//生成事件发布实例Alarm alarm = new Alarm();heater.WaterEvent += alarm.Waring;//对事件发布方进行订阅(侦听),反之我们使用-=取消订阅heater.HeatWater();//触发事件,那么现在Alarm类对象alarm将会侦听到这次事件
通过上述例子我们就大致的了解了事件的工作情况,以及事件发布方和事件侦听方的概念。
.Net平台为我们提供了泛型委托EventHandler<T>,有了这个泛型委托之后我们就不在需要定义委托类了。我们来看看泛型委托EventHandler<T>的原型:
public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e)where TEventArgs: EventArgs;参数列表中第一个参数是对象,包含事件的发送者,第二个参数提供了事件的相关信息。现在我们定义事件时,只需让基本数据类继承EventArgs,然后我们就能泛型委托来定义事件了。
注意:事件只能在本类型内部“触发”,委托不管在本类型内部还是外部都可以“调用”。事件在类的外部只能使用+=或-=来增加/取消订阅
- 委托、Lambda表达式和事件
- 委托,Lambda表达式和事件
- 委托、Lambda表达式和事件
- 委托,lambda表达式和事件
- 委托、Lambda表达式和事件
- c# 委托、事件、lambda表达式
- C#委托/Lambda表达式/事件
- 委托,Lambda表达式与事件
- 深入解析C# 委托事件和Lambda表达式
- [连载]C#程序设计(15)--- 委托、事件和Lambda表达式
- 学习笔记--委托,Lambda表达式和事件(1)
- 学习笔记--委托,Lambda表达式和事件(2)
- C#高级编程之委托、lambda表达式和事件
- C#高级学习第二章委托,Lambda表达式和事件
- (八)委托、Lambda和事件
- 委托、匿名委托和lambda表达式
- C# 委托 事件 匿名函数 Lambda表达式
- 委托、冒泡排序、lambda表达式、事件
- springMvc 数据绑定,类型转换,数据校验 解析
- 浅谈Html5的优势和劣势
- HDOJ 2824 The Euler function (欧拉函数)
- spring MVC中定义异常页面
- c++无限输入求和,非数组
- 委托,lambda表达式和事件
- spring boot-jpa整合QueryDSL来简化复杂操作
- bzoj 1036: [ZJOI2008]树的统计Count
- LeetCode 38. Count and Say 字符串“阅读式”扩张
- 分组统计
- JAVA程序员必看的15本书
- Leetcode 68. Text Justification
- (c语言)将一个二维数组的行列互换
- C. Bank Hacking----思维题