Thứ Bảy, ngày 07 tháng 8 năm 2010

// // Leave a Comment

Sự Khác Nhau Giữa Delegate Và Event

Chúng ta có thể làm những điều tương tự với cả hai cách sử dụng delegate và event, và dường như chúng chỉ khác nhau về cú pháp khai báo?
Bạn và tôi sẽ cùng nhau phân biệt delegate và event thông qua các ví dụ dưới đây, xem sự rõ ràng của chúng trong cách sử dụng.
Dưới đây là cú pháp khai báo:

Delegate:
public class VubkaDelegate
{
public delegate void ExampleDelegate(); public ExampleDelegate DeleageteCallback;
}
Event:
public class VubkaEvent
{
public delegate void ExampleEvent(); public event ExampleEvent EventCallback;
}

Như vậy ta mới thấy được sự khác nhau của chúng cơ bản thông qua từ khóa event
Và có một câu hỏi đặt ra là tại sao chúng ta có thêm 1 từ khóa mà trong khi ta vẫn có thể hoàn tất công việc nếu như không sử dụng nó (thiếu từ khóa event).
Vấn đề đặt ra là sự tồn tại của từ khóa event trong cách khai báo một sự kiện có ý nghĩa như thế nào. Tiếp tục ví dụ trên, cùng xem cách sử dụng chúng như thế nào đối với lớp này
VubkaDelegate _vubkaDelegate = new VubkaDelegate(); _vubkaDelegate.DelegateCallback += new VubkaDelegate.ExampleDelegate(SayHello);
Ta sẽ thêm vào danh sách gọi hàm của delegate. Đoạn mã tương tự trên vẫn tiếp tục hoạt động và dường như không có vấn đề gì cả
VubkaEvent _vubkaEvent = new VubkaEvent(); _vubkaEvent.EventCallback += new VubkaEvent.ExampleEvent(SayHello);
Bây giờ, ta sẽ thử thay thế cách thêm danh sách gọi hàm của delegate , đơn giản ta chỉ gán delegate tới new delegate (sử dụng phép gán =, không phải là +=)
Ta sẽ thử thay đoạn mã như sau:
VubkaDelegate _vubkaDelegate = new VubkaDelegate(); _vubkaDelegate.DelegateCallback = new VubkaDelegate.ExampleDelegate(SayHello);

Với đoạn mã trên thì nó hoạt động tốt nhưng nó sẽ không thể áp đặt cho 1 event :D
Và điều này có nghĩa là chúng ta sử dụng từ khóa event thì không có lớp client nào có thể áp đặt cho nó trỏ tới null. Điều này là hết sức quan trọng. Nhiều client có thể sử dụng delegate giống nhau. Sau khi chúng đã trỏ thêm 1 hàm để nghe (listen) lời gọi lại (callback) của delegate. Nhưng giờ 1 client áp đặt delegate trỏ tới null hoặc sử dụng dấu = để gán tới 1 lời gọi mới. Điều này có nghĩa danh sách gọi hàm trước đó bị mất hết.
Do đó tất cả các client trước đó sẽ không thể thực hiện bất kỳ 1 lời gọi nào nều như chúng đã đăng ký gọi hàm trước đó.
Kết luận:
- Chúng ta có thể nói rằng từ khóa event nó có thêm 1 tầng bảo vệ cho các thể hiện (instance) của delegate. Nó chống lại bất cứ client nào thiết đặt lại danh sách lời gọi hàm. Và chúng chỉ có thể thêm hoặc loại bỏ đích trỏ hàm đang tồn tại trong danh sách gọi hàm.
- Và bản thân event chỉ giúp ta đăng ký hoặc loại bỏ (bởi 2 toán tử += hoặc -=) gọi hàm cho delegate khi có sự kiện xảy ra.

Dưới đây là đoạn mã đầy đủ cho ví dụ trên:
Download: Program.cs
using System;
using System.Collections.Generic;
using System.Text;

namespace BKIndex.Vunb.Net.Assigment1
{
    class Program
    {
        static void Main(string[] args)
        {
            // Declare instances Delegate and Event
            VubkaDelegate _vubkaDelegate = new VubkaDelegate();
            VubkaEvent _vubkaEvent = new VubkaEvent();

            _vubkaDelegate.DelegateCallback += new VubkaDelegate.ExampleDelegate(SayHello);
            _vubkaEvent.EventCallback += new VubkaEvent.ExampleEvent(SayHello);

            _vubkaDelegate.DelegateCallback.Invoke();   // using Invoke method
            _vubkaEvent.Fire();
            Console.WriteLine("------------");
            _vubkaDelegate.DelegateCallback += new VubkaDelegate.ExampleDelegate(SayHello);
            _vubkaEvent.EventCallback += new VubkaEvent.ExampleEvent(SayHello);

            _vubkaDelegate.DelegateCallback();
            _vubkaEvent.Fire();
            Console.WriteLine("------------");
            _vubkaDelegate.DelegateCallback = null;
            // Or
            _vubkaDelegate.DelegateCallback = SayHello;

            /* not OK 
            // _vubkaEvent.EventCallback = new VubkaEvent.ExampleEvent(SayHello);
            // _vubkaEvent.ExampleEvent = null;
            */
            Console.WriteLine("NOT OK!!!");
            Console.WriteLine("------------");

            /* Only sign, OK */
            _vubkaEvent.EventCallback -= SayHello;

            _vubkaDelegate.DelegateCallback();
            _vubkaEvent.Fire();
        }

        static void SayHello()
        {
            Console.WriteLine("Hello!");
        }
    }

    public class VubkaDelegate
    {
        public delegate void ExampleDelegate();
        public ExampleDelegate DelegateCallback;
    }

    public class VubkaEvent
    {
        public delegate void ExampleEvent();
        public event ExampleEvent EventCallback;

        protected virtual void OnEventCallback()
        {
            if (EventCallback != null)
                EventCallback();
        }

        public void Fire()
        {
            OnEventCallback();
        }
    }
}
Bạn nên xem qua định nghĩa về delegate và event trước khi đọc bài này:
Delegate và Event trong C#
Delegate là gì?

0 comments: