C# Academy · Урок

События: публикация и подписка, ключевое слово event

Публикуйте события и подписывайтесь на них: объявляйте событие, добавляйте и удаляйте обработчики, передавайте данные через EventArgs и вызывайте событие по шаблону OnX.

Урок 2 из 38 шагов

«События: публикация и подписка, ключевое слово event» — бесплатный урок C# Academy на CoddyKit. Это урок 2 из 3. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 3 уроков всего.

Обзор событий

Цель: организовать публикацию и подписку с помощью событий.

  • Объявлять событие у издателя
  • Подписываться с помощью +=, отменять подписку с помощью -=
  • Безопасно инициировать событие у издателя
  • Передавать данные с помощью EventArgs

Основы использования событий

Предоставьте событие и позвольте слушателям подключаться к нему и отключаться от него. Вызывать событие может только издатель.

using System;

public class Button
{
  public event EventHandler Click;

  public void SimulateClick()
  {
    // Safe raise: copy then invoke if not null (C# 6-safe)
    EventHandler h = Click;
    if (h != null) h(this, EventArgs.Empty);
  }
}

public class Program
{
  static void OnClick(object sender, EventArgs e)
  {
    Console.WriteLine("Clicked!");
  }

  public static void Main(string[] args)
  {
    Button b = new Button();
    b.Click += OnClick;    // subscribe
    b.SimulateClick();     // prints "Clicked!"

    b.Click -= OnClick;    // unsubscribe
    b.SimulateClick();     // no output
  }
}

Событие с данными

Используйте EventArgs (или EventHandler<TEventArgs>), чтобы передавать подписчикам полезные данные.

using System;

// Data for the event
public sealed class PriceChangedEventArgs : EventArgs
{
  public decimal OldPrice { get; private set; }
  public decimal NewPrice { get; private set; }
  public PriceChangedEventArgs(decimal oldP, decimal newP)
  {
    OldPrice = oldP; NewPrice = newP;
  }
}

public sealed class Product
{
  private decimal _price;
  public event EventHandler<PriceChangedEventArgs> PriceChanged;

  public decimal Price
  {
    get { return _price; }
    set
    {
      if (value != _price)
      {
        decimal old = _price;
        _price = value;
        EventHandler<PriceChangedEventArgs> h = PriceChanged;
        if (h != null) h(this, new PriceChangedEventArgs(old, _price));
      }
    }
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    Product p = new Product();
    p.PriceChanged += delegate(object s, PriceChangedEventArgs e)
    {
      Console.WriteLine("Price: " + e.OldPrice + " -> " + e.NewPrice);
    };
    p.Price = 10m;
    p.Price = 12m;
  }
}

Групповая рассылка и лямбда-выражения

События поддерживают многоадресную рассылку: несколько обработчиков выполняются в порядке подписки. Используйте именованные или анонимные обработчики.

using System;

public class Alarm
{
  public event EventHandler Ring;

  public void Trigger()
  {
    EventHandler h = Ring;
    if (h != null) h(this, EventArgs.Empty);
  }
}

public class Program
{
  static void HandlerA(object s, EventArgs e) { Console.WriteLine("A"); }
  static void HandlerB(object s, EventArgs e) { Console.WriteLine("B"); }

  public static void Main(string[] args)
  {
    Alarm a = new Alarm();
    a.Ring += HandlerA;                           // named
    a.Ring += delegate(object s, EventArgs e) { Console.WriteLine("lambda"); }; // anon
    a.Ring += HandlerB;

    a.Trigger(); // prints A, lambda, B (multicast order)
  }
}

Шаблон инициирования OnX

Используйте защищённый метод OnX для инициирования событий. Скопируйте делегат в локальную переменную и проверьте его на null перед вызовом.

using System;

public class Ticker
{
  public event EventHandler Tick;

  protected virtual void OnTick()
  {
    EventHandler h = Tick;          // copy to local
    if (h != null) h(this, EventArgs.Empty);
  }

  public void RunOnce()
  {
    // do work...
    OnTick(); // raise via protected method
  }
}

public class Program
{
  static void Show(object s, EventArgs e) { Console.WriteLine("Tick!"); }

  public static void Main(string[] args)
  {
    Ticker t = new Ticker();
    t.Tick += Show;
    t.RunOnce();
  }
}

Советы и подводные камни событий

Советы:

  • Всегда отменяйте подписку ( -= ), когда подписчик больше не нужен.
  • Делайте обработчики короткими; длительную работу следует ставить в очередь.
  • Используйте EventArgs (или производный класс) для передачи данных.
  • Инициировать событие должен только издатель.

Роль ключевого слова event

Быстрая проверка: какое ключевое слово C# предоставляет делегат для подписки и отмены подписки, не позволяя внешнему коду напрямую вызывать его?

Повторение

Повторение: объявляйте событие, позволяйте слушателям подключаться к нему и отключаться от него, передавайте данные с помощью EventArgs и инициируйте событие через защищённый метод OnX.

Можно начать бесплатно

Изучай C# с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
93
Уроки
346

Часто задаваемые вопросы

Урок «События: публикация и подписка, ключевое слово event» бесплатный?

Да — полный текст урока «События: публикация и подписка, ключевое слово event» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 3 уроков всего.

Чему я научусь в уроке «События: публикация и подписка, ключевое слово event»?

Публикуйте события и подписывайтесь на них: объявляйте событие, добавляйте и удаляйте обработчики, передавайте данные через EventArgs и вызывайте событие по шаблону OnX. Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C# Academy?

Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 3.

Сколько времени занимает урок «События: публикация и подписка, ключевое слово event»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C# Academy?

Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Делегаты, Action/Func и замыкания
  2. События: публикация и подписка, ключевое слово event
  3. Шаблоны событий и подводные камни (утечки памяти)
← Назад к C# Academy