I am trying to properly check if an object's event has already been set to a specific method.
That stackoverflow question offers 2 solutions :
I have several questions related to the second solution. Let's assume the following code
public static class Util
{
public static bool IsRegistered<T>(this EventHandler<T> handler, Delegate prospectiveHandler)
=> handler != null
&& handler.GetInvocationList().Any(existingHandler => existingHandler == prospectiveHandler));
}
public class Object1
{
public event EventHandler<string> OnSomething;
public bool CheckOnSomething(Delegate handler) => this.OnSomething.IsRegistered(handler);
}
public class Object2
{
private Object1 o;
public Object2(Object1 o1)
{
this.o = o1;
}
public void CatchSomething(object sender, string something)
{
// ...
}
public void HookToSomething()
{
if (!o.CheckOnSomething( ??? ))
o.OnSomething += this.CatchSomething;
}
}
CheckOnSomething
, i need to pass a delegate to CatchSomething
. Do i have to define a new delegate for that, or is there already something i can use ?false
?In order to call
CheckOnSomething
, I need to pass a delegate toCatchSomething
. Do I have to define a new delegate for that, or is there already something I can use ?
You could pass CatchSomething
directly:
if (!o.CheckOnSomething(CatchSomething))
o.OnSomething += CatchSomething;
But you would need to update CheckOnSomething
to accept a specific delegate type, so that CatchSomething
can be converted:
public bool CheckOnSomething(Action<object, string> handler)
=> this.OnSomething.IsRegistered(handler);
This improves type-safety also, because only delegates with the correct signature can now be passed.
If I define a new delegate, will the delegate equality work ? The documentation says it checks for the delegate type, but since I pass the method directly, isn't a new delegate type created on the fly, which would make the equality always return false ?
Passing the method creates a new delegate instance not a new delegate type; the delegate type will always be Action<object, string>
.
However, delegate equality relies on target as well as type, so passing CatchSomething
will only be considered equal if it is form the same instance.
For example:
var obj1 = new Object1();
var instance1 = new Object2(obj1);
// Creates a delegate instance:
Action<object, string> catchSomething = instance1.CatchSomething;
catchSomething == instance1.CatchSomething; // true
var instance2 = new Object2(obj1);
catchSomething == instance2.CatchSomething; // false