1》
委托与事件的区别:
1.委托可以在声明它的类外部进行调用,而事件只能在类的内部进行调用。
2.委托是一个类型,事件修饰的是一个对象
总结:
总结: 参考资料:事件与委托的区别
1、委托可以把一个方法作为参数代入另一个方法。 委托可以理解为指向一个函数的指针。
2、委托和事件没有可比性,因为委托是类型,事件是对象
3、其实事件是委托的一个修饰符,加了event(事件)修饰之后,委托就被阉割了,假设这个加了修饰符的事件称为事件1,通过事件1我们可以更好地控制注册和注销,也就是对于一个外部类,那么他只能“注册自己+=、注销自己-=”,例如上面的ClassA,如果我们事件的注册是在ClassA内部进行的,那么它就只能注册自己内部的方法到事件上。另外,外界也不能主动地触发一个事件。事件只能add、remove自己,不能赋值。也就是说事件只能+=、-=,不能= 。当我们反编译以上例子的源程序的时候,我们可以发现事件内部就是一个private的委托和add,remove两个方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication3
{
//声明一个委托: 委托可以定义在类里面,但是一般我们不那样做,除非特殊情况。因为委托是和类平级的,所以委托一般定义在namespace下面
//委托说白了就是一个数据类型,就像string 类型接收字符串数据 int类型接收整形数据, 而委托类型接收方法
public delegate void MyDelegate();
public class Test
{
//创建一个委托的实例
public MyDelegate mydel;
//声明一个事件: 事件只能在类的内部声明
public event MyDelegate EventMyDel;
/// <summary>
/// 事件触发机制(必须和事件在同一个类中)外界无法直接用EventMyDel()来触发事件
/// </summary>
public void DoEventMyDel()
{
//事件后面加一个括号,括号的意思就代表执行这个事件
EventMyDel();
}
}
public class Founc
{
public void Fun_A()
{
Console.WriteLine("A方法被触发");
}
public void Fun_B()
{
Console.WriteLine("B方法被触发");
}
public void Fun_C()
{
Console.WriteLine("C方法被触发");
}
}
class Program
{
static void Main(string[] args)
{
Test test = new Test();
Founc founc = new Founc();
//注册委托(将委托绑定到方法)
test.mydel = test.mydel + founc.Fun_A; //将委托实例挂载到了A方法 [注意,注册委托是可以用=号来进行注册的]
test.mydel += founc.Fun_B; //将委托实例挂载到B方法
//执行委托
//test.mydel(); //输出结果是 [ A方法被触发 B方法被触发 ]
//这时候我们来对委托进行干扰(其实这里的所谓的“干扰”,就是给以存在的委托链中附加了一个 null 的对象,然后在给委托附加C方法)
test.mydel = null;
test.mydel += founc.Fun_C;
//再次执行委托(注意,先把上面那个执行委托注释掉,这样才能看到干扰后的结果嘛)
test.mydel(); //输出结果 [ C方法被触发 ]
/*大家想想,为什么会这样呢??为什么A,B方法不执行了呢??这是因为原来的委托链 是已经挂载了A,B两个方法了,但这时突然被干扰了下,又附加了一个null对象,破坏了原有的委托链了,但这又说明了什么呢?因为委托本质就是一个类, 它包含一对有用的字段,第一个字段是存放该对象的引用,第二个字段存放一个方法的指针,所以我们可以把委托理解成一个指向函数的指针,当一个方法作为参数 赋值给一个委托的时候,该委托就指向了该方法的首地址,即方法名,所以当我们给委托注册A,B两个方法,该委托就同时指向了A,B两个方法的首地址,但这 是又突然给委托赋值了,且赋值了一个null对象,注意这里用的是赋值符号[=],这就是说让该委托清除原有的指针指向,此时指向一个null,之后又给 委托注册了C方法,所以此时委托即指向null,又指向了C方法的首地址,这就是为什么运行时只会看到C方法被触发的原因了!
那就是说现在的委托变得不安全了,哪天一个项目中给委托注册了很多方法,但突然被干扰了下,前面的注册都失效了,那我们前面做的工作不是白做了,那有没有办法可以防止这种干扰呢??答案是当然有,相信聪明的你也应该猜到了,这时就是事件该上场的时候了。
*/
/*==================================================*/
//注册事件(将事件绑定到方法)。没法对事件用赋值[=]号来进行注册,需要用+=这种形式
test.EventMyDel += founc.Fun_B; //将事件绑定到B方法
test.EventMyDel += null; //即便这个时候对事件进行干扰
test.EventMyDel += founc.Fun_C; //将事件绑定到C方法
//执行事件触发事件的方法
test.DoEventMyDel(); //输出结果是 [ B方法被触发 C方法被触发 ],即使你附加了一个null对象,2个方法照样依次执行了,,这就是事件的封装效果了
Console.ReadKey();
}
}
}
<2>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace 委托学习
{
delegate int Mydelegate(int a, int b);//该委托的参数一定要与下面的M1方法参数一致,这样在把M1方法当做参数传给委托的时候就不会报错(错误1 :“M1”的重载均与委托“委托学习.Mydelegate”不匹配)
public class A
{
public static int M1(int x, int y)
{
int z = x + y;
return z;
}
}
class Program
{
static void Main(string[] args)
{
//委托是对方法的封装
Mydelegate d = new Mydelegate(A.M1); //实例化一个委托,注意M1方法后面是没有带小括号的,如果带小括号的话就等于执行该M1方法了,会报错的
int sum=d(5, 6);
Console.WriteLine(sum);
Console.ReadKey();
}
}
}
<2>事件与委托的区别
通俗的讲,委托你可以在客户代码中直接调用委托来激发委托指向的函数,而事件不可以,事件的触发只能由服务代码自己触发
也就是说在你的代码里委托你不但可以安排谁是它的调用函数,还可以直接调用它,而事件不能直接调用,只能通过某些操作触发
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace 委托学习2
{
public delegate void Mydalegate(string message);
//事件的本质就是一个委托。事件,就当给委托起了一个别名
class EventClass
{
public event Mydalegate MyEvent;
public void DoEvent(string mes) //注意这个方法参数要与委托的参数一致。
{
MyEvent(mes);
}
}
class Program
{
public void A(string mes)
{
Console.WriteLine(mes + "11111");
}
public void B(string mes)
{
Console.WriteLine(mes + "22222");
}
public void C(string mes)
{
Console.WriteLine(mes + "33333");
}
static void Main(string[] args)
{
//-----------------------------------------------------委托
Program p=new Program ();
//注册委托(将委托绑定到A方法) ,非常重要的一点,委托是可以用=号来进行注册(挂载)的,而事件只能用+=来注册
Mydalegate mydel = p.A;
mydel("委托"); //执行委托,输出 委托11111
//将委托再挂载到B方法,这时候委托就已经挂载到两个方法上了。形成了委托链
mydel += p.B;
mydel("委托"); //执行委托,输出 委托11111 委托22222
//将委托链上的A方法删除掉
mydel -= p.A;
mydel("委托"); //执行委托,这里时候委托链上只有一个B方法了。所以这里输出 委托22222
//那么现在对委托进行干扰。将委托重新指向了一个null,这时候他已经破坏了委托链了。之前注册的方法已经被清空。
mydel = null;
//mydel("委托"); //报错:未将对象引用设置到对象的实例。
//注册委托(将委托绑定到C方法)
mydel += p.C;
mydel("委托"); //执行委托,输出 委托33333
//----------------------------------------------------事件
EventClass e = new EventClass();
//注册事件(将事件绑定到方法)。无法对事件用赋值[=]号来进行注册,需要用+=这种形式 ,这是一种规定
e.MyEvent += p.A;
e.DoEvent("事件"); //执行DoEvent方法,方法内部是一个事件的执行。输出 事件11111
e.MyEvent += p.B;
e.DoEvent("事件"); //执行DoEvent方法,方法内部是一个事件的执行。输出事件11111 事件22222
Console.ReadKey();
}
}
}
http://www.cnblogs.com/holyknight-zld/archive/2012/08/30/delegateEvent.html
本文深入解析了委托与事件的概念及区别,通过实例演示了委托如何绑定和触发方法,以及事件如何提供更安全的触发机制。文章还展示了委托与事件在.NET编程中的应用。
&spm=1001.2101.3001.5002&articleId=27324251&d=1&t=3&u=a7d9bb74bf2044babcd4ef77bb2c32a1)
3650

被折叠的 条评论
为什么被折叠?



