程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 委托筆記(二)

委托筆記(二)

編輯:C#入門知識

上一篇:http://www.BkJia.com/kf/201206/134062.html

委托與事件的經典示例:


using System;
using System.Collections.Generic;
using System.Text;

namespace Delegate
{
    // 熱水器
    public class Heater
    {
        private int temperature;
        public string type = "RealFire 001";              // 添加型號作為演示
        public string area = "China Xian";                     // 添加產地作為演示
        //聲明委托
        public delegate void BoiledEventHandler(Object sender, BoliedEventArgs e);
        public event BoiledEventHandler Boiled;       //聲明事件

        // 定義BoliedEventArgs類,傳遞給Observer所感興趣的信息
        public class BoliedEventArgs : EventArgs
        {
            public readonly int temperature;
            public BoliedEventArgs(int temperature)
            {
                this.temperature = temperature;
            }
        }

        // 可以供繼承自 Heater 的類重寫,以便繼承類拒絕其他對象對它的監視
        protected virtual void OnBolied(BoliedEventArgs e)
        {
            if (Boiled != null)
            {       // 如果有對象注冊
                Boiled(this, e);       // 調用所有注冊對象的方法
            }
        }

        // 燒水。
        public void BoilWater()
        {
            for (int i = 0; i <= 100; i++)
            {
                temperature = i;
                if (temperature > 98)
                {
                    //建立BoliedEventArgs 對象。
                    BoliedEventArgs e = new BoliedEventArgs(temperature);
                    OnBolied(e);       // 調用 OnBolied方法
                }
            }
        }
    }

    // 警報器
    public class Alarm
    {
        public void MakeAlert(Object sender, Heater.BoliedEventArgs e)
        {
            Heater heater = (Heater)sender;              //這裡是不是很熟悉呢?
            //訪問 sender 中的公共字段
            Console.WriteLine("Alarm:{0} - {1}: ", heater.area, heater.type);
            Console.WriteLine("Alarm: 嘀嘀嘀,水已經 {0} 度了:", e.temperature);
            Console.WriteLine();
        }

    }

    // 顯示器 www.2cto.com
    public class Display
    {
        public static void ShowMsg(Object sender, Heater.BoliedEventArgs e)
        {       //靜態方法
            Heater heater = (Heater)sender;
            Console.WriteLine("Display:{0} - {1}: ", heater.area, heater.type);
            Console.WriteLine("Display:水快燒開了,當前溫度:{0}度。", e.temperature);
            Console.WriteLine();
        }
    }

    class Program
    {
        static void Main()
        {
            Heater heater = new Heater();
            Alarm alarm = new Alarm();

            heater.Boiled += alarm.MakeAlert;       //注冊方法
            heater.Boiled += Display.ShowMsg;              //注冊靜態方法

            heater.BoilWater();       //燒水,會自動調用注冊過對象的方法

            Console.ReadKey();
        }
    }
}
輸出:

Alarm:China Xian - RealFire 001:
Alarm: 嘀嘀嘀,水已經 99 度了:

Display:China Xian - RealFire 001:
Display:水快燒開了,當前溫度:99度。

Alarm:China Xian - RealFire 001:
Alarm: 嘀嘀嘀,水已經 100 度了:

Display:China Xian - RealFire 001:
Display:水快燒開了,當前溫度:100度。

 

一開始我也不明白為什麼要使用EventArgs參數,看下面

 

.Net Framework的編碼規范:

委托類型的名稱都應該以EventHandler結束。
委托的原型定義:有一個void返回值,並接受兩個輸入參數:一個Object 類型,一個 EventArgs類型(或繼承自EventArgs)。
事件的命名為 委托去掉 EventHandler之後剩余的部分。
繼承自EventArgs的類型應該以EventArgs結尾。
上面這些其實不僅僅是為了編碼規范而已,這樣也使得程序有更大的靈活性。比如說,如果我們不光想獲得熱水器的溫度,還想在Observer端(警報器或者顯示器)方法中獲得它的生產日期、型號、價格,那麼委托和方法的聲明都會變得很麻煩,而如果我們將熱水器的引用傳給警報器的方法,就可以在方法中直接訪問熱水器了。

 

 

摘自 Fly to The Moon

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved