Musisz zaimplementować add and remove accessors na zdarzeniu, a następnie sprawdzić listę docelową delegata lub przechowywać cele w lista.
W metodzie dodawania można użyć metody Delegate.GetInvocationList, aby uzyskać listę celów już dodanych do uczestnika.
Ponieważ delegaci są zdefiniowani tak, aby porównać je równomiernie, jeśli są połączeni z tą samą metodą na tym samym obiekcie docelowym, prawdopodobnie można uruchomić tę listę i porównać, a jeśli nie znajdziesz równego porównania, dodaj nowy .
Oto przykładowy kod, skompilować jako aplikacji konsoli:
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");
}
}
}
wyjściowa:
tc_Test called
(czyli tylko raz.)
Musisz użyć System.Linq używając. –
Wystarczy wyjaśnić komentarz Hermanna; musisz dodać przestrzeń nazw "System.Linq", dodając "using System.Linq" do swojej klasy lub aktualnej przestrzeni nazw. –
Fascynujące. LINQ jest dla mnie wystarczająco nowy, że muszę go sprawdzić i przypomnieć, że to znaczy Zintegrowane Zapytanie językowe ... i zastanawiam się, co to ma wspólnego z EventHandlers i ich InvocationList? – fortboise