Procedura: pubblicare eventi conformi alle indicazioni di .NET Framework (Guida per programmatori C#)
Aggiornamento: novembre 2007
Nella procedura seguente viene illustrato come aggiungere eventi conformi al modello standard di .NET Framework per classi e strutture. Tutti gli eventi nella libreria di classi di .NET Framework sono basati sul delegato EventHandler che è definito nel modo seguente:
public delegate void EventHandler(object sender, EventArgs e);
Nota: |
---|
.NET Framework 2.0 introduce una versione generica di questo delegato, EventHandler<TEventArgs>. Negli esempi seguenti viene illustrato come utilizzare entrambe le versioni. |
Nonostante gli eventi definiti in classi possano essere basati su qualsiasi tipo delegato valido, inclusi i delegati che restituiscono un valore, è in genere consigliabile basare gli eventi sul modello di .NET Framework utilizzando l'oggetto EventHandler, come illustrato nell'esempio seguente:
Per pubblicare eventi basati sul modello EventHandler
Ignorare questo passaggio e andare direttamente al passaggio 3a se non è necessario inviare dati personalizzati con l'evento. Dichiarare la classe in un ambito visibile a entrambe le classi publisher e subscriber e aggiungere i membri necessari per includere i dati dell'evento personalizzato. In questo esempio viene restituita una semplice stringa.
public class CustomEventArgs : EventArgs { public CustomEventArgs(string s) { msg = s; } private string msg; public string Message { get { return msg; } } }
(Ignorare questo passaggio se si utilizza la versione generica di EventHandler<TEventArgs>.) Dichiarare un delegato nella classe di pubblicazione. Assegnargli un nome che termini con EventHandler. Il secondo parametro specifica il tipo EventArgs personalizzato.
public delegate void CustomEventHandler(object sender, CustomEventArgs a);
Dichiarare l'evento nella classe di pubblicazione eseguendo una delle operazioni seguenti.
Se non si dispone di una classe EventArgs personalizzata, il tipo di evento sarà il delegato EventHandler non generico. Non è necessario dichiararlo perché è già dichiarato nello spazio dei nomi System incluso quando si crea il progetto C#:
public event EventHandler RaiseCustomEvent;
Se si utilizza la versione non generica di EventHandler e si dispone di una classe personalizzata derivata da EventArgs, dichiarare l'evento all'interno della classe di pubblicazione e utilizzare il delegato come tipo:
class Publisher { public event CustomEventHandler RaiseCustomEvent; }
Se si utilizza la versione generica, non è necessario un delegato personalizzato. Specificare il tipo di evento come EventHandler<CustomEventArgs>, sostituendo il nome della classe racchiuso tra parentesi angolari.
public event EventHandler<CustomEventArgs> RaiseCustomEvent;
Esempio
Nell'esempio riportato di seguito vengono illustrati i passaggi indicati sopra utilizzando una classe EventArgs personalizzata e EventHandler<TEventArgs> come tipo di evento.
namespace DotNetEvents
{
using System;
using System.Collections.Generic;
// Define a class to hold custom event info
public class CustomEventArgs : EventArgs
{
public CustomEventArgs(string s)
{
message = s;
}
private string message;
public string Message
{
get { return message; }
set { message = value; }
}
}
// 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("Did something"));
}
// 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> handler = RaiseCustomEvent;
// Event will be null if there are no subscribers
if (handler != null)
{
// Format the string to send inside the CustomEventArgs parameter
e.Message += String.Format(" at {0}", DateTime.Now.ToString());
// Use the () operator to raise the event.
handler(this, e);
}
}
}
//Class that subscribes to an event
class Subscriber
{
private string id;
public Subscriber(string ID, Publisher pub)
{
id = ID;
// Subscribe to the event using C# 2.0 syntax
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: {0}", e.Message);
}
}
class Program
{
static void Main(string[] args)
{
Publisher pub = new Publisher();
Subscriber sub1 = new Subscriber("sub1", pub);
Subscriber sub2 = new Subscriber("sub2", pub);
// Call the method that raises the event.
pub.DoSomething();
// Keep the console window open
Console.WriteLine("Press Enter to close this window.");
Console.ReadLine();
}
}
}
Vedere anche
Concetti
Riferimenti
Eventi (Guida per programmatori C#)