搜了委托的示例,也会提到事件,但是演示 委托功能时,可以不用事件
但是,搜索所有事件的例子,基本都会有委托
用事件时,一定要委托么 ?
再有,为什么要使用事件? 什么情况下适合使用事件?
------解决思路----------------------
事件就是一种委托
------解决思路----------------------
Sender sender = new Senser();
Receiver receiver = new Receiver(sender);
sender.TriggerEvent();
------解决思路----------------------
http://www.cnblogs.com/xuting/archive/2008/08/26/1276318.html
推荐
------解决思路----------------------
事件本质上是委托,其实自己用的时候很少,在windows窗体程序中,编写事件的方法时自动通过委托将事件与指定的方法进行委托
------解决思路----------------------
事件即委托,是用来减少依赖的。 一个类的方法如何让别人调用,可以new、可以用静态,还可以把 这个方法传递出去,跟传递一个参数一样。
------解决思路----------------------
额,我这么说你可明白“事件必须是委托,委托未必是事件”
好了不需要再说啥了,中学滴哲学课,数学课都这么教滴,你应该能理解了把(充分和必要)
------解决思路----------------------
至于什么情况下是什么
事件可以用委托代替,委托不一定能用事件代替
常规情况下:“必须依靠外面才能确定方法,使用委托;而不需要外面的方法,甚至是从class内部发出滴通知外面接收的东西,使用事件”
大体上是这样
1.我委托你办事,这事我办不好,必须委托你来办--这是委托
2.我已经办好,需要通知你来接收(当然你接不接收,可以有,可以没有,反正我已经办好)--这是事件
------解决思路----------------------
收集的代码 事件和委托
委托会在后面赋值的时候被覆盖,事件赋值一个执行一个,一下收集的测试代码
----------------系统委托EventHandler
----------------------------事件(封装)
public event SearchHandler search;
public event SearchHandler Search {
add {
search += value;
}
remove {
search -= value;
}
}
--------------------------------------------------------------------简单的委托例子
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace T2
{
//委托必须是参数类型和返回类型相同,并且用deletegate修饰
class Computer
{
public int Add(int x, int z) {
return x + z;
}
public int Sub(int x, int z)
{
return x - z;
}
//属性委托
public delegate int ComputerHander(int x, int z);
public ComputerHander ch=null;
}
//类委托
public delegate int ComputerHander(int x, int z);
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace T2
{
class Program
{
static void Main(string[] args)
{
//Computer的例子
Computer c = new Computer();
//调用类委托
ComputerHander hander = c.Add;
Console.WriteLine(hander(1,2));
//调用属性委托
c.ch = c.Sub;
Console.WriteLine(c.ch(1, 2));
}
}
}
--------------------------------------------------------------用方法做参数的委托
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace T2
{
//定义一个业务逻辑类
class HelloManager
{
//把委托作为方法的参数
public void SayHello(string name, HelloHander hander) {
hander(name);
}
}
//定义中国人类
class Chinaes
{
public static void ChinesHello(string name) {
Console.WriteLine("ChinesHello," + name);
}
}
//定义英国人类
class English
{
public static void EnglishHello(string name)
{
Console.WriteLine("EnglishHello," + name);
}
}
//定义委托
public delegate void HelloHander(string name);
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace T2
{
class Program
{
static void Main(string[] args)
{
//调用HelloManager的例子
HelloManager h = new HelloManager();
h.SayHello("哈哈",English.EnglishHello);
}
}
}
------------------------------------------------------------------自定义事件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace T2
{ //自定义注册事件
//猫是事件原,所以事件类型要在猫类里面定义
class Cat
{
//定义委托
public delegate void CryHander();
//定义事件,委托类型
public event CryHander CryEvent;
public void Cry() {
Console.WriteLine("猫大叫一声...");
if (CryEvent != null) {
CryEvent();//执行事件
}
}
}
//老鼠
class Mouse {
public void Run() {
Console.WriteLine("老鼠逃跑了....");
}
}
//主人
class Master {
public void Weak() {
Console.WriteLine("主人醒了....");
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace T2
{
class Program
{
static void Main(string[] args)
{
//动态注册事件
Cat cat = new Cat();
Mouse mouse = new Mouse();
Master master = new Master();
//订阅事件,多播性
cat.CryEvent += new Cat.CryHander(mouse.Run);
cat.CryEvent += new Cat.CryHander(master.Weak);
//触发事件
cat.Cry();
}
}
}
--------------------------------------带参数的事件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace T2
{
//事件类型
public class QuestionEvenArgs : EventArgs
{
public string QuestionMes{get; set; }
}
//委托
public delegate void QuestionHander(object sendr,QuestionEvenArgs e);
//主持人类
public class Host
{
public event QuestionHander AnswerQuestion;
public string Name { get; set; }
public string Question { get; set; }//问题
//触发事件方法
public void Start()
{
Console.WriteLine("大家好,我是:" + Name);
Console.WriteLine("今天的问题是:" + Question);
Console.WriteLine("请各位嘉宾开始回答");
//通知所有嘉宾回答问题
if (AnswerQuestion != null)
{
AnswerQuestion(this, new QuestionEvenArgs { QuestionMes = Question });
}
}
}
//嘉宾抽象类--父类
public abstract class Guest {
public string Name { get; set; }
public abstract void Answer(object sendr, QuestionEvenArgs e);
}
public class GuestA : Guest
{
public override void Answer(object sendr, QuestionEvenArgs e)
{
Console.WriteLine(Name + ",这个问题是我考虑一下!");
}
}
public class GuestB : Guest
{
public override void Answer(object sendr, QuestionEvenArgs e)
{
Console.WriteLine(Name + ",这个问题我知道!");
}
}
public class GuestC : Guest {
public override void Answer(object sendr, QuestionEvenArgs e)
{
Host h = sendr as Host;
Console.WriteLine(h.Name+",这个问题是"+e.QuestionMes+",我知道答案,但是我不告诉你");
}
}
public class Test {
public static void Main(string[] args) {
Host h = new Host { Name = "李咏", Question = "伦敦奥运什么时候开始?" };
GuestA a = new GuestA { Name = "AAA" };
GuestB b = new GuestB { Name = "BBB" };
GuestC c = new GuestC { Name = "CCC" };
h.AnswerQuestion += new QuestionHander(a.Answer);
h.AnswerQuestion += new QuestionHander(b.Answer);
h.AnswerQuestion += new QuestionHander(c.Answer);
h.Start();
}
}
}
------解决思路----------------------
测试的时候,main函数里面直接初始化两个类,不过要先初始化Sender类,因为后面的Receiver类的构造函数需要传递一个Sender类的对象,两个类单独对象都初始化好后,调用Sender类的对象的方法TriggerEvent,次方法本来应该只输出"Trigger an event.",但是由于初始化Receiver类的时候,其内部绑定了事件,因此会自动触发OnEvent方法,同步输出"Received and handled an event."。
这个例子说明了一个现象,虽然Receiver类OnEvent方法没有手动去执行,但是会因Sender类的对象的方法TriggerEvent的执行而一起被执行,这就是事件的触发。
不过这个例子有一个BUG,就是当Receiver类未初始化的话,Sender类的对象的方法TriggerEvent执行会报错,那个Event为空,没做是否为空判断。
------解决思路----------------------
一句话概括:事件就是封装了的委托类型变量
事件的用途就是暴露出需要自定义处理的方法,方便程序员使用,例如点击按钮事件,点击这个动作是不变的,但点击之后要干的事是不同的,所以封装好一个点击事件,程序员就可以方便的实现功能了
------解决思路----------------------
对于代码 public event EventHandler Event; 来说,这个 Event 是你暴露的一个名称,就好像属性名称似地,是用来引用一个对象的。而EventHandler则是Event的类型声明。
你也可以写 public EventHandler Event; 也就是不写关键字 event。这就是声明了一个叫做Event的委托实例,但是它不是事件。
------解决思路----------------------
什么时候用事件/委托?
我不调用它,让它主动调用我。
比如说,当网络上传来一些数据,当数据库发生改变需要通知主程序,当收到电子邮件,当用户按下一个按钮。这些场合显然不适合你不断去调用对方程序检查状态,而由对方在合适的时机主动调用你。