Is adding (or removing) an empty event listener no-op?

Usually the answers to such questions can be found here or, if not here, on MSDN, but I looked and looked and did not find the answer. The experiment seems to show code like:

SomeControl.Click += null;

does no harm. Or, at least, what fires the event does not throw an exception (I can say), trying to call a null event listener. Nevertheless, it seems that there is nowhere on the Web that confirms my hope that such code does not do at least what I may not want to do. For example, triggering a Click event to think that it has listeners when it might be wrong, and spend those precious super-ultra-mini-microseconds on "now allow you to perform null checks and call all listeners that are not null" code.

It seems that the documentation should say that the behavior of the operators + = and - = if the listener on the RHS is null. But, as I said, I can not find this documentation anywhere. I'm sure someone here can provide this, though ....

(Obviously, my code does not have hardcoded zero, my question is whether such code is wasteful or completely safe:

public static void AddHandlers([NotNull] this Button button,
                               [CanBeNull] EventHandler click = null,
                               [CanBeNull] EventHandler load = null)
{
    button.Click += click;
    button.Load += load;
}

or if I need (that is, for some reason) add null checks around each such operation + =.)

+4
source share
2 answers

Consider this code:

void Main()
{
    var foo = new Foo();
    foo.Blah += Qaz;
    foo.Blah += null;
    foo.OnBlah();
}

public void Qaz()
{
    Console.WriteLine("Qaz");
}

public class Foo
{
    public event Action Blah;
    public void OnBlah()
    {
        var b = Blah;
        if (b != null)
        {
            Console.WriteLine("Calling Blah");
            b();
            Console.WriteLine("Called Blah");
        }
    }
}

Like it works without errors and produces the following output:

Calling Blah
Qaz
Called Blah

If I delete the line foo.Blah += Qaz;, then the code runs without errors, but does not output the result, so the handler is nullactually ignored.

Regarding IL, the line foo.Blah += null;produces the following IL:

IL_001A:  ldloc.0     // foo
IL_001B:  ldnull      
IL_001C:  callvirt    Foo.add_Blah
IL_0021:  nop 

So, it behaves like nop, but explicitly executes the code.

+2
source

, += ( -=) .

AddHandlers Button, , Click Load , . , += add - . button.Click += value; :

button.add_Click(value);

, add_Click , Button.

, Button Click. :

private EventHandler _click;
public event EventHandler Click
{
    add { _click += value; }
    remove { _click -= value; }
}

// Or even shorter...
// public event EventHandler Click;
// ... which is the same as above plus extra stuff for thread safety.

EventHandler . , += Delegate.Combine. , Delegate.Combine(a, b) :

, a b . a, b null, b, a , , b .

: Button ( , , , List<EventHandler>), button.Click += null; .

+3

Source: https://habr.com/ru/post/1617549/


All Articles