频道栏目
首页 > 资讯 > C# > 正文

c#的委托delegate事件的详细使用

17-09-12        来源:[db:作者]  
收藏   我要投稿

一、无参数,无返回的委托事件

委托事件类、事件的发生源。1.声明委托 2定义事件 3具体方法

 1 public class Test
 2 {
 3     // ….
 4   public delegate void TestHandler();//无参数,无返回委托
 5   public event TestHandler TestEvent;//事件
 6   public void OnTestHandler()//调用
 7   {
 8     if(TestEvent != null) //不等于null 说明该事件已经注册有函数
 9     {
10       this.TestEvent();
11     }
12   }
13 }

调用触发事件方法(这里把注册和调用写在一起,实际可以把注册写在另外的类)

 1 class Program
 2 {
 3   static void Main(string[] args)
 4   {
 5     Test model = new Test();//实列
 6     model.TestEvent += model_TestEvent;//为model 注册TestEvent事件的执行方法
 7     model.OnTestHandler();//调用引发事件
 8   }
 9   static void model_TestEvent()//事件执行方法,该方法样式要与委托一致(参数,返回值)
10   {
11     Console.WriteLine("这是最简单的事件");
12   }
13 }

执行效果

补充1、委托链。通过+= 添加执行函数。

 1 model.TestEvent += model_TestEvent;//为model 注册TestEvent事件的执行方法,符合TestHandler委托样式(参数,返回值)的方法都可以进行注册,可注册多个函数,按顺序执行。如改为
 2 model.TestEvent += model_TestEvent1;
 3 //model.TestEvent += new Test.TestHandler(model_TestEvent1);也可以这样写
 4 model.TestEvent += model_TestEvent2;
 5 static void model_TestEvent1()
 6 {
 7   Console.WriteLine("这是事件的函数1");
 8 }//可设置断点看执行顺序
 9 static void model_TestEvent2()
10 {
11   Console.WriteLine("这是事件的函数2");
12 }

执行效果

补充2、委托事件 结合在发布订阅者模式中。

Main(string[] args)方法中我们进行了注册和调用,像观察者模式使用,就会把注册和调用进行分开。

注册类,也就是所谓的订阅类。该类也可以写成接口,给不同业务的监听者用来继承扩张,这里所有监听者都执行model_TestEvent()函数。

 1 public class Listeners
 2 {
 3   //注册
 4   public void registerEvent(Test model)
 5   {
 6     model.TestEvent += newTest.TestHandler(model_TestEvent);
 7   }
 8   //注销
 9   public void nullifyEvent(Test model)
10   {
11     model.TestEvent -= newTest.TestHandler(model_TestEvent);
12   }
13   public virtual void model_TestEvent()
14   {
15     Console.WriteLine("这是所有监听者要执行的函数");
16   }
17 }

这里原来是注册事件,现在改为实例,注册监听者。。

 1 static void Main(string[] args)
 2 {
 3   Test model = new Test();
 4   //可以实例注册多个监听者
 5   Listeners listener1 = new Listeners();
 6   Listeners listener2 = new Listeners();
 7   listener1.registerEvent(model);
 8   listener2.registerEvent(model);
 9 
10   model.OnTestHandler(); //事件触发后,会向所有注册的监听者发送,所有监听者执行函数model_TestEvent
11 }

执行效果

 

二、带参数、返回值的委托事件

首先定义事件的参数,这是自定义事件传入的参数,从Eventargs继承,也可直接用Eventargs,这里为了简单就只给了个string字段,利用构造函数赋值。

一般带返回的委托事件,不会采用+=,因为委托链的话,非void,会忽略前面的函数,只会返回最后一个函数的结果。

1 public class TestEventArgs : EventArgs
2 {
3   public string parameters;
4   public TestEventArgs(string par)
5   {
6     parameters = par;
7   }
8 }

委托事件类

 1 public class Test
 2 {
 3   public delegate string TestHandler(object sender, TestEventArgs tea);//带参数,带返回的委托
 4   public event TestHandler TestEvent; //定义事件
 5   public string OnTestEvent(TestEventArgs tea)//调用
 6   {
 7     if (TestEvent != null)
 8     {
 9       return TestEvent(this,tea);
10     }
11     return null;
12   }
13 }

注册触发

 1 static void Main(string[] args)
 2 {
 3   Test model = new Test();
 4   model.TestEvent += model_TestEvent;//注册事件
 5   TestEventArgs tea = new TestEventArgs("test");//事件传入参数
 6   string result=  model.OnTestEvent(tea) ;//事件触发,得到结果
 7   Console.WriteLine(result);
 8 }
 9 static string model_TestEvent(object sender, TestEventArgs tea)
10 {
11   return "传入的参数是:" +tea.parameters ;
12 }

补充1、

这里注册和触发同样可以分开,前面的注册类中把model_TestEvent改为

 1 public virtual string model_TestEvent(objectsender,TestEventArgs tea)//事件执行函数
 2 {
 3   return "传入的参数是:" +tea.parameters;
 4 }
 5 class Program
 6 {
 7   static void Main(string[] args)
 8   {
 9     Test model = new Test();//实例
10     Listeners listener = new Listeners();//实例监听
11     listener.registerEvent(model);//注册
12     TestEventArgs tea = new TestEventArgs("test"); //事件参数
13     string result= model.OnTestEvent(tea);
14     Console.WriteLine(result);
15   }
16 }

补充2、

事件参数类型也可以封装,放在Test类内(OnTestEvent改为privte)。在Test类内加多

 1 public string InitEvent(string par)
 2 {
 3   TestEventArgs tea = new TestEventArgs(par);
 4   return OnTestEvent(tea);
 5 }
 6 Main就可以改为
 7 static void Main(string[] args)
 8 {
 9   Test model = new Test();
10   Listeners listener = new Listeners();
11   listener.registerEvent(model);//监听者注册到Test.这里如果很多不同业务的监听者的话,如何返回所有监听者处理完的信息。修改Listeners类?(单例,管理者类)。
12   string result = model.InitEvent("test");
13   Console.WriteLine(result);
14 }

完毕!多多指教。

相关TAG标签
上一篇:sizeof与strlen的区别与联系
下一篇:网易云课堂-数据结构-第一讲-基本概念
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站