Debe implementar agregar y quitar accesos en el evento, y luego verificar la lista de objetivos del delegado, o almacenar los objetivos en un lista.
En el método add, puede usar el método Delegate.GetInvocationList para obtener una lista de los objetivos que ya se han agregado al delegado.
Dado que los delegados se definen para comparar iguales si están vinculados al mismo método en el mismo objeto de destino, probablemente podría ejecutar esa lista y comparar, y si no encuentra ninguno que compare igual, agregue el nuevo .
Aquí es código de ejemplo, los datos como aplicación de consola:
using System;
using System.Linq;
namespace DemoApp
{
public class TestClass
{
private EventHandler _Test;
public event EventHandler Test
{
add
{
if (_Test == null || !_Test.GetInvocationList().Contains(value))
_Test += value;
}
remove
{
_Test -= value;
}
}
public void OnTest()
{
if (_Test != null)
_Test(this, EventArgs.Empty);
}
}
class Program
{
static void Main()
{
TestClass tc = new TestClass();
tc.Test += tc_Test;
tc.Test += tc_Test;
tc.OnTest();
Console.In.ReadLine();
}
static void tc_Test(object sender, EventArgs e)
{
Console.Out.WriteLine("tc_Test called");
}
}
}
Salida:
tc_Test called
(es decir, sólo una vez).
Necesita usar System.Linq usando. –
Solo para aclarar el comentario de Hermann; debe incluir el espacio de nombres 'System.Linq' agregando 'using System.Linq' a su clase o espacio de nombres actual. –
Fascinante. LINQ sigue siendo lo suficientemente nuevo para mí que tengo que buscarlo y recordarle que significa Language Integrated Query ... y luego me pregunto qué tiene que ver eso con EventHandlers y su InvocationList. – fortboise