当前位置: 代码迷 >> C# >> 用 事件 时,务必 要委托么
  详细解决方案

用 事件 时,务必 要委托么

热度:685   发布时间:2016-05-05 03:49:13.0
用 事件 时,必须 要委托么?
搜了委托的示例,也会提到事件,但是演示 委托功能时,可以不用事件


但是,搜索所有事件的例子,基本都会有委托

用事件时,一定要委托么 ? 

再有,为什么要使用事件? 什么情况下适合使用事件?

------解决思路----------------------
事件就是一种委托
------解决思路----------------------

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();
        }
    }
}


------解决思路----------------------
引用:



  public class Sender
        {
            public delegate void EventHandler(object sender);
            public event EventHandler Event;

            public void TriggerEvent()
            {
                Console.WriteLine("Trigger an event.");
                Event(this);
            }
        }

        public class Receiver
        {
            public Receiver(Sender sender)
            {
                sender.Event += new Sender.EventHandler(OnEvent);
            }
            private void OnEvent(object sender)
            {
                Console.WriteLine("Received and handled an event.");
                Console.Read();
            }
        }





 看到一个例子,不知道如何试验结果

控制台程序

 main()
 如何把这两个类关联起来? 谢谢

测试的时候,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的委托实例,但是它不是事件。
------解决思路----------------------
什么时候用事件/委托?

我不调用它,让它主动调用我。

比如说,当网络上传来一些数据,当数据库发生改变需要通知主程序,当收到电子邮件,当用户按下一个按钮。这些场合显然不适合你不断去调用对方程序检查状态,而由对方在合适的时机主动调用你。
  相关解决方案