1. 程式人生 > >c#中的delegate(委托)和event(事件)

c#中的delegate(委托)和event(事件)

sel 指針 添加 自動 關鍵字 only cnblogs 私有 part

委托: 托付其他人做這件事 ,包括 托付自己 ,即 一個方法 可以 調用 沒有關系的其他方法 , 也可以 將委托傳遞過去 ,回調自己的方法 ,且 可以自定義參數 ,非常方便 互相傳值, 適合解耦 關系。

示例:

public delegate void ChangeMoney(object s, int n); // 用 delegate 聲明委托

1、 調用 其他方法

售賣 頁面添加商品,添加 的 商品 在另一個頁面也能看見 。

售賣頁面 類裏面 定義委托:

//定義一個委托
public delegate void GetProductHander(List<MarkingModel> mlist);
// 將創建的委托和特定事件關聯
public static event GetProductHander getproduct;

//點擊添加商品時 調用 委托方法:

if(點擊添加商品)

{

getproduct.Invoke(_list);

}

另一個頁面調用委托:

ProductSaleMarketing.getproduct += new ProductSaleMarketing.GetProductHander(GetList);

// 將 要調用的 GetList 方法 放到 getproduct (從類裏面點出來)後面。 以及實現 GetList 方法

private void GetList(List<MarkingModel> _mlist)
{

}

2. 相當於回調方法

這個要在類外面定義委托 ,因為 回調 是 在其他頁面實例化委托 ,調用 連接的方法。 誰在後邊 後邊調用誰。

public delegate void ChangeMoney(object s, int n); // 在頁面外邊 聲明委托 其他頁面都可調用

public partial class TiHuoBill : BaseForm
{

//多窗口共用事件
private void sn_EveDelSelectNumber(object cash, int n)
{
ChangePay(cash, n);
}


//現金
private void btnCash_Click(object sender, EventArgs e)
{
var sn = new ShowNumber(7);
sn.CardMoney = _daishou;
sn.EveDelSelectNumber += sn_EveDelSelectNumber; // 主要就是 這句話 委托在ShowNumber 頁面 實例化了, += 即 那個頁面執行後 調用 sn_EveDelSelectNumber
sn.ShowDialog();
}

}

ShowNumber 頁面 :

public ChangeMoney EveDelSelectNumber; // 實例化委托

// 確定關閉頁面的時候

private void btnSure_Click(object sender, EventArgs e)
{

EveDelSelectNumber(SelectMoney, SelectType); // 調用委托 並傳值 或者這種方式: EveDelSelectNumber.Invoke(SelectMoney, SelectType);

}

暫時發現 委托 可以使用這兩種方式

其中 delegate 和 event 效果 是一樣的

區別 :event與delegate的區別
首先,通過加入event關鍵字,在編譯的時候編譯器會自動針對事件生成一個私有的字段(與此事件相關的委托),以及兩個訪問器方法,即add訪問器方法以及remove訪問器方法,用於對事件的註冊及註銷(對事件使用+=及-=操作時就是調用的這兩個方法)。
我想你們的問題主要是,實際上聲明一個委托類型的字段也可以實現這些功能。
實際上之所以采用event而不直接采用委托,實際上還是為了封裝。可以設想一下,如果直接采用公共的委托字段,類型外部就可以對此字段進行直接的操作了,比如將其直接賦值為null。
而使用event關鍵字就可以保證對事件的操作僅限於add訪問器方法以及remove訪問器方法(即只能使用+=及-=)

在Msdn中,有一段話描述Delegate和Event之間的關系,其實很簡單:

聲明事件:若要在類內聲明事件,首先必須聲明該事件的委托類型。

委托還適用於 觀察者模式:

    class Program
    {
        static void Main(string[] args)
        {
            var car = new Car(15);
            new Alerter(car);
            car.Run(120);
        }
    }

    class Car
    {
        public delegate void Notify(int value);
        public event Notify notifier;

        private int petrol = 0;
        public int Petrol
        {
            get { return petrol; }
            set
            {
                petrol = value;
                if (petrol < 10)  //當petrol的值小於10時,出發警報
                {
                    if (notifier != null)
                    {
                        notifier.Invoke(Petrol);
                    }
                }
            }
        }

        public Car(int petrol)
        {
            Petrol = petrol;
        }

        public void Run(int speed)
        {
            int distance = 0;
            while (Petrol > 0)
            {
                Thread.Sleep(500);
                Petrol--;
                distance += speed;
                Console.WriteLine("Car is running... Distance is " + distance.ToString());
            }
        }
    }

    class Alerter
    {
        public Alerter(Car car)
        {
            car.notifier += new Car.Notify(NotEnoughPetrol);
        }

        public void NotEnoughPetrol(int value)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("You only have " + value.ToString() + " gallon petrol left!");
            Console.ResetColor();
        }
    }

看完了上面的代碼後,你可能會問:為什麽不在public int Petrol中直接調用Alerter.NotEnoughPetrol呢?因為Car模塊和Alerter模塊本身是兩個獨立的子系統,如果直接調用,耦合性就會增加,這不是我們願意看到的。

其實以上的代碼是設計模式中的觀察者模式(觀察者模式又稱Source/Listener模式)的實現,當汽車在運行中汽油量<10時,警報器便會發出警報。在上面代碼中,Delegate相當於一個存放回調函數的函數指針,使用Delegate,我們可以非常方便地實現觀察者模式。而其實,在需要使用回調函數時,我們都可以考慮使用Delegate。

不知道你有沒有發現在上面的代碼中還有一個問題呢?

public event Notify notifier;

上面的代碼中,我們定義了一個Event,而事實上:

public Notify notifier;

這樣寫,也完全可以滿足我們的需求,這就引出了我們的另一個問題,Delegate和Event! 如上 有說明。

參考: 談C#中的Delegate

event與delegate的區別

終於會用c#中的delegate(委托)和event(事件)了

c#中的delegate(委托)和event(事件)