關於c#的事件如何使用


c#的委托delegate事件的詳細使用

一、無參數,無返回的委托事件

委托事件類、事件的發生源。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 }

 完畢!多多指教。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM