C # events and class methods

I am wondering if I do something like this:

class A { public MethodA() { } public MethodB() { ExternalObject.Click += this.MethodA; } public MethodC() { ExternalObject.Click -= this.MethodA; } } A a = new A(); a.MethodB(); a.MethodC(); 

Will this work? By “work” I mean - will MethodA cancel the subscription to the ExternalObject.Click event?

And other related questions:

What happens behind the scenes when the instance method is used instead of the delegate instance? (e.g. above)

Does this cause implicit delegate creation?

How does the -= operator perform comparisons between delegates - by reference, or maybe something more complicated is happening?

+6
source share
2 answers

Yes, it will work the way you want it.

The comparison is not by reference, but by value, which means that you can unsubscribe from another delegate if he points to the same method on the same object.

In other words, this will work very well:

 var delegate1 = new ExternalObjectClickEventHandler(MethodA); var delegate2 = new ExternalObjectClickEventHandler(MethodA); ExternalObject.Click += delegate1; ExternalObject.Click -= delegate2; 

Anonymous methods are different, but you cannot do this:

 public MethodB() { ExternalObject.Click += () => { return 10; }; } public MethodC() { ExternalObject.Click -= () => { return 10; }; } 

Although the methods contain the same code, they are considered different, and therefore this will not work, that is, MethodC will not cancel the subscription that you added to MethodB .

To solve this problem, you need to save the delegate between calls, for example:

 private ExternalObjectClickEventHandler _ClickEventHandler; public MethodB() { _ClickEventHandler = () => { return 10; }; ExternalObject.Click += _ClickEventHandler; } public MethodC() { ExternalObject.Click -= _ClickEventHandler; } 

But the code you showed will work.

As for your question, what happens behind the scenes is that the following two lines of code are identical when it comes to the generated code:

 ExternalObject.Click += MethodA; ExternalObject.Click += new ExternalObjectClickEventHandler(MethodA); 

The second code is what is generated from the first (it is assumed that the type of the event is indicated as.)

The first syntax was (at some point) added as "syntactic sugar", which is translated by the compiler as if you had written the second syntax. Note that this only happens if the compiled one can determine the correct type to 100%. I saw some cases (which I cannot remember right now) where you had to use fully qualified syntax because the compiler could not understand what you had in mind. In particular, overload methods and generics can confuse him in this regard.

+8
source

Yes, MethodA will be unsubscribed.

About the second question, I'm not 100% sure, but I think = this.MethodA converts to a delegate in the background.

+3
source

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


All Articles