Bagikan melalui


Cara menerbitkan peristiwa yang sesuai dengan Panduan .NET (Panduan Pemrograman C#)

Prosedur berikut menunjukkan cara menambahkan peristiwa yang mengikuti pola .NET standar ke kelas dan struktur Anda. Semua peristiwa di pustaka kelas .NET Framework didasarkan pada delegasi EventHandler, yang didefinisikan sebagai berikut:

public delegate void EventHandler(object? sender, EventArgs e);

Catatan

.NET Framework 2.0 memperkenalkan versi generik dari delegasi ini, EventHandler<TEventArgs>. Contoh berikut menunjukkan cara menggunakan kedua versi.

Meskipun peristiwa di kelas yang Anda tentukan dapat didasarkan pada jenis delegasi yang valid, bahkan delegasi yang mengembalikan nilai, umumnya disarankan agar Anda mendasarkan peristiwa pada pola .NET dengan menggunakan EventHandler, seperti yang ditunjukkan dalam contoh berikut.

Nama EventHandler dapat menyebabkan sedikit kebingungan karena tidak benar-benar menangani peristiwa. EventHandler, dan EventHandler<TEventArgs> generik adalah jenis delegasi. Metode atau ekspresi lambda yang tanda tangannya cocok dengan definisi delegasi adalah penanganan aktivitas dan akan dipanggil saat peristiwa dimunculkan.

Menerbitkan peristiwa berdasarkan pola EventHandler

  1. (Lewati langkah ini dan lanjutkan ke Langkah 3a jika Anda tidak perlu mengirim data kustom dengan peristiwa Anda.) Deklarasikan kelas untuk data kustom Anda pada cakupan yang terlihat oleh kelas penerbit dan pelanggan Anda. Lalu tambahkan anggota yang diperlukan untuk menyimpan data peristiwa kustom Anda. Dalam contoh ini, string sederhana dikembalikan.

    public class CustomEventArgs : EventArgs
    {
        public CustomEventArgs(string message)
        {
            Message = message;
        }
    
        public string Message { get; set; }
    }
    
  2. (Lewati langkah ini jika Anda menggunakan versi generik EventHandler<TEventArgs>.) Deklarasikan delegasi di kelas penerbitan Anda. Beri nama yang diakhiri dengan EventHandler. Parameter kedua menentukan jenis EventArgs kustom Anda.

    public delegate void CustomEventHandler(object? sender, CustomEventArgs args);
    
  3. Deklarasikan peristiwa di kelas penerbitan Anda dengan menggunakan salah satu langkah berikut.

    1. Jika tidak memiliki kelas EventArgs kustom, jenis Peristiwa Anda akan menjadi delegasi EventHandler non-generik. Anda tidak perlu mendeklarasikan delegasi karena sudah dideklarasikan di namespace System yang disertakan saat Anda membuat proyek C#. Tambahkan kode berikut ke kelas penerbit Anda.

      public event EventHandler? RaiseCustomEvent;
      
    2. Jika Anda menggunakan EventHandler versi non-generik dan memiliki kelas kustom yang berasal dari EventArgs, deklarasikan peristiwa Anda di dalam kelas penerbitan dan gunakan delegasi dari langkah 2 sebagai jenisnya.

      public event CustomEventHandler? RaiseCustomEvent;
      
    3. Jika menggunakan versi generik, Anda tidak memerlukan delegasi kustom. Sebagai gantinya, di kelas penerbitan, Anda menentukan jenis peristiwa sebagai EventHandler<CustomEventArgs>, menggantikan nama kelas Anda sendiri di antara tanda kurung sudut.

      public event EventHandler<CustomEventArgs>? RaiseCustomEvent;
      

Contoh

Contoh berikut menunjukkan langkah-langkah sebelumnya dengan menggunakan kelas EventArgs kustom dan EventHandler<TEventArgs> sebagai jenis peristiwa.

namespace DotNetEvents
{
    // Define a class to hold custom event info
    public class CustomEventArgs : EventArgs
    {
        public CustomEventArgs(string message)
        {
            Message = message;
        }

        public string Message { get; set; }
    }

    // Class that publishes an event
    class Publisher
    {
        // Declare the event using EventHandler<T>
        public event EventHandler<CustomEventArgs>? RaiseCustomEvent;

        public void DoSomething()
        {
            // Write some code that does something useful here
            // then raise the event. You can also raise an event
            // before you execute a block of code.
            OnRaiseCustomEvent(new CustomEventArgs("Event triggered"));
        }

        // Wrap event invocations inside a protected virtual method
        // to allow derived classes to override the event invocation behavior
        protected virtual void OnRaiseCustomEvent(CustomEventArgs e)
        {
            // Make a temporary copy of the event to avoid possibility of
            // a race condition if the last subscriber unsubscribes
            // immediately after the null check and before the event is raised.
            EventHandler<CustomEventArgs>? raiseEvent = RaiseCustomEvent;

            // Event will be null if there are no subscribers
            if (raiseEvent != null)
            {
                // Format the string to send inside the CustomEventArgs parameter
                e.Message += $" at {DateTime.Now}";

                // Call to raise the event.
                raiseEvent(this, e);
            }
        }
    }

    //Class that subscribes to an event
    class Subscriber
    {
        private readonly string _id;

        public Subscriber(string id, Publisher pub)
        {
            _id = id;

            // Subscribe to the event
            pub.RaiseCustomEvent += HandleCustomEvent;
        }

        // Define what actions to take when the event is raised.
        void HandleCustomEvent(object? sender, CustomEventArgs e)
        {
            Console.WriteLine($"{_id} received this message: {e.Message}");
        }
    }

    class Program
    {
        static void Main()
        {
            var pub = new Publisher();
            var sub1 = new Subscriber("sub1", pub);
            var sub2 = new Subscriber("sub2", pub);

            // Call the method that raises the event.
            pub.DoSomething();

            // Keep the console window open
            Console.WriteLine("Press any key to continue...");
            Console.ReadLine();
        }
    }
}

Lihat juga