C# event 事件


  事件第二篇:https://www.cnblogs.com/FavoriteMango/p/11731485.html

  曾經面試碰到一道設計題:

  現有一個人,一群鳥,人有一把手槍,當人開槍時,所有的鳥都被嚇飛了。要求按照題干設計程序且有一定的擴展性。

當時我並無任何的程序設計知識,看到該題一點解決辦法也沒有,按照面向過程完全可以寫流程出來,但“光寫流程”並不符合C#面向對象的的思想,寫出來也不具有任何擴展性。

直到后來學習了事件的相關知識,可能目前仍然不清楚如何擴展,但至少可以寫個像模像樣的程序出來。

1.事件的組成

事件的組成分為5個部分:

(1)事件的擁有者

(2)事件本身

(3)事件的訂閱者

(4)事件處理器

(5)訂閱事件

  事件的擁有者,或者說這件事的發起者,以上題為例,人開槍,人便是發起事件的對象,是事件的擁有者;事件的本身,開槍這件事便是事情的本身;事件的訂閱者,也就是關注事件發生的對象,題中開槍后鳥都飛走了,鳥是聽到槍響才飛走的,也就是說鳥是關注“開槍”這件事的對象;事件處理器,訂閱者在關注到事件發生后,針對事件作出的反應。鳥在槍響后都被嚇得飛走了,“飛走”便是它們針對“開槍”作出的事件處理。此外,事件的發生和事件處理都是一種動作,兩者緊密相連卻又互不相同,在處理事件的邏輯時一定要分清二者的界限,切不可混為一談而導致邏輯混亂;而訂閱事件,這實際是一種關系,這個關系是聯系擁有者和訂閱者、事件和事件處理的一個“紐帶”。就好比你家里做好了飯,家里人通知你飯做好了,你知道要開飯了於是趕緊回家,因為你是“關注”家里“開飯”這件事的,這便是訂閱事件。

2.事件的使用

  定義事件的關鍵字是event,並且事件定義時需要搭配委托,語法:修飾符 + event + 委托類型 + 名稱。

  事件的觸發只能在被聲明該事件的類中進行,語法與類方法調用相同,所以事件是不能直接在類體之外觸發的,若想在程序的其他地方觸發方法,必須要用類方法在類體中封裝事件。

  事件的訂閱需要用到“+=”操作符,語法:實體類名稱.事件 += 方法(事件處理器)。由於事件依托委托來聲明,所以一個事件可以掛接多個事件處理器,也就是說可以被多個對象訂閱。

  回到題目,理清楚題目中的對象分別對應組成事件的哪個部分,人是事件的發起者、開槍是事件本身,鳥是事件的訂閱者,它訂閱了開槍這件事,而飛走是它對開槍這件事的處理。寫成代碼大概是下面這個樣子:

 

//人

public class Man
{

  //人的事件(這里用了執行無參數無返回值方法的委托類型)
  public event Action Fire;

  //封裝了事件的類方法

  public void Action()
  {
    if (Fire != null)
    {
      Console.WriteLine("人開槍了");
      //觸發事件

      Fire();
    }
  }  
}

 

//鳥

public class Bird
{
  public string birdName { get; set; }

  //聲明一個集合類型的靜態字段,用於保存實例化的所有Bird類

  public static List<Bird> Birds = new List<Bird>();

  //這是鳥類對於開槍的事件處理器

  internal static void Fly()
  {
    for (int i = 0; i < Birds.Count; i++)
    {
      Console.WriteLine(Birds[i].birdName + "飛走了");
    }
  }

  //每一次實例化都會在構造函數中保存當前實例化的Bird類

  public Bird()
  {
    Birds.Add(this);
  }
}

 

class Program
{
  static void Main(string[] args)
  {

    //實例化對象
    Man man = new Man();

    //訂閱事件,聯結兩類對象中的事件和事件處理器
    man.Fire += Bird.Fly;

    //循環生成Bird類
    for (int i = 0; i < 5; i++)
    {
      Bird bird = new Bird();
      bird.birdName = "小鳥" + i;
    }

    //調用封裝事件的方法,觸發事件
    man.Action();
  }

}

 

 

 

 

  


免責聲明!

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



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