Публикация событий, соответствующих рекомендациям .NET (руководство по программированию на C#)
Следующая процедура демонстрирует добавление событий, которые соответствуют стандартному шаблону .NET для классов и структур. Все события в библиотеке классов .NET основаны на делегате EventHandler, который определен следующим образом:
public delegate void EventHandler(object? sender, EventArgs e);
Примечание.
В .NET Framework 2.0 представлена универсальная версия этого делегата, EventHandler<TEventArgs>. В следующих примерах демонстрируется использование обеих версий.
Хотя события в определяемых классах могут быть основаны на любом допустимом типе делегата, даже на делегатах, возвращающих значение, обычно рекомендуется основывать события на шаблоне .NET с помощью EventHandler, как показано в следующем примере.
Имя EventHandler
может привести к путанице, так как на самом деле этот делегат не обрабатывает событие. Делегат EventHandler и универсальный делегат EventHandler<TEventArgs> являются типами делегатов. Метод или лямбда-выражение, сигнатура которого соответствует определению делегата, является обработчиком событий и будет вызываться при возникновении события.
Публикация событий, основанных на шаблоне EventHandler
(Пропустите этот шаг и перейдите к шагу 3a, если вам не нужно отправлять пользовательские данные с событием.) Объявите класс для пользовательских данных в область, который отображается как для издателя, так и для подписчиков. Затем добавьте необходимые члены для хранения пользовательских данных о событиях. В этом примере возвращается простая строка.
public class CustomEventArgs : EventArgs { public CustomEventArgs(string message) { Message = message; } public string Message { get; set; } }
(Пропустить этот шаг, если вы используете универсальную версию EventHandler<TEventArgs>.) Объявите делегат в классе публикации. Присвойте ему имя, которое заканчивается на
EventHandler
. Второй параметр указывает настраиваемый типEventArgs
.public delegate void CustomEventHandler(object? sender, CustomEventArgs args);
Объявите событие в своем классе публикации, выполнив одно из следующих действий.
Если у вас нет пользовательского класса EventArgs, тип события будет неуниверсальным делегатом EventHandler. Нет необходимости объявлять делегат, так как он уже объявлен в пространстве имен System, которое включается при создании проекта C#. Добавьте следующий код в класс Publisher.
public event EventHandler? RaiseCustomEvent;
Если вы используете неуниверсальную версию EventHandler и имеется пользовательский класс, производный от EventArgs, объявите событие внутри класса публикации и используйте делегат из шага 2 в качестве типа.
public event CustomEventHandler? RaiseCustomEvent;
Если используется универсальная версия, пользовательский делегат не требуется. Вместо этого в классе публикации укажите тип события как
EventHandler<CustomEventArgs>
, подставив имя своего класса в угловые скобки.public event EventHandler<CustomEventArgs>? RaiseCustomEvent;
Пример
В следующем примере показана вышеописанная процедура с использованием пользовательского класса EventArgs и EventHandler<TEventArgs> в качестве типа событий.
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();
}
}
}
См. также
Кері байланыс
https://aka.ms/ContentUserFeedback.
Жақында қолжетімді болады: 2024 жыл бойы біз GitHub Issues жүйесін мазмұнға арналған кері байланыс механизмі ретінде біртіндеп қолданыстан шығарамыз және оны жаңа кері байланыс жүйесімен ауыстырамыз. Қосымша ақпаратты мұнда қараңыз:Жіберу және пікірді көру