Sie müssen die hinzufügen und entfernen Zugriffsmethoden auf das Ereignis, und überprüfen Sie dann die Zielliste des Delegaten, oder speichern Sie die Ziele in einem Liste.
In der Methode add können Sie mit der Methode Delegate.GetInvocationList eine Liste der Ziele abrufen, die dem Delegaten bereits hinzugefügt wurden.
Da Delegaten für den Vergleich von "Gleich" definiert sind, wenn sie mit derselben Methode für dasselbe Zielobjekt verknüpft sind, können Sie diese Liste möglicherweise durchlaufen und vergleichen. Wenn Sie keine Gleichheit finden, fügen Sie die Neue hinzu .
Hier ist Beispielcode kompilieren als Konsolenanwendung:
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");
}
}
}
Ausgang:
tc_Test called
(dh nur einmal.)
Sie müssen das System.Linq mit verwenden. –
Nur um Hermanns Kommentar zu klären; Sie müssen den Namespace 'System.Linq' hinzufügen, indem Sie 'using System.Linq' zu Ihrer Klasse oder dem aktuellen Namespace hinzufügen. –
Faszinierend. LINQ ist mir noch neu genug, dass ich es nachschlagen muss und daran erinnert werden muss, dass es sich um eine sprachintegrierte Abfrage handelt ... und frage mich dann, was das mit EventHandlern und ihrer InvocationList zu tun hat? – fortboise