C # events, what's with this zero thing?

I canโ€™t understand what this zero testing is when you raise an event.

Say I have this code.

class ballClass { public event EventHandler BallInPlay; public void onHit() { if (BallInPlay != null) { BallInPlay(this, new EventArgs()); } else { MessageBox.Show("null!"); } } } 

and I want to raise BallInPlay even when I run the onHit () method.

right now he is showing me that BallInPlay IS null. how or with what should I โ€œfillโ€ it in order for it to work?

Thanks!

+4
source share
7 answers

You need to subscribe to the event using a handler. For instance:

 BallClass ball = new BallClass(); ball.BallInPlay += BallInPlayHandler; // Now when ball.OnHit is called for whatever reason, BallInPlayHandler // will get called ... private void BallInPlayHandler(Object sender, EventArgs e) { // React to the event here } 

For more information, you can read my article on events and delegates .

Please note that I fixed the BallClass and OnHit above - it is a good idea to use standard .NET naming conventions so that your code fits better into the code around it, and to make it more readable for others.

One note: the invalidation check that you have received so far is not thread safe. The last subscriber can unsubscribe after if , but before the call. Safe version:

 public void OnHit() { EventHandler handler = BallInPlay; if (handler != null) { handler(this, new EventArgs()); } else { MessageBox.Show("null!"); } } 

This is not guaranteed to be used by the latest subscribers (since there is no memory barrier), but it is guaranteed that it will not rule out a NullReference exception due to race conditions.

+7
source

The fact is that if zero listeners are registered to listen to this event, it will be raised, the event is null. If one or more listeners are registered, it will matter.

This means that if null listeners are registered, and you try to raise this event without performing a null check, your program throws an exception.

+8
source

The null test is one because if NOONE LISTENING is for an event, the event object that you call swuold is actually null. Thus, without subscribers, you will get a null pointer exception.

+2
source

If no event handlers are assigned to the event, the event is null. Think of an event like List, when there are no elements in the list, the value of the event becomes null .

Attempting to raise an event when there are no event handlers assigned to it throws a NullReferenceException.

Zero checking prevents a NullReferenceException.

If you want BallInPlay to work, you need to add an EventHandler .

Your code will be something like this:

BallInPlay += new EventHandler(YourFunctionNameGoesHere);

+2
source

A null test is to determine if something is listening for an event. When something attaches an event handler, BallInPlay will no longer be null

+1
source
 BallInPlay(this, new EventArgs()); 

The reason for checking null before triggering the event will become apparent if you understand that the above line of code is indeed compiled, as if you wrote the following:

 BallInPlay.Invoke(this, new EventArgs()); // ^^^^^^^ 

And, as we all know, it is a bad idea to call a method in a null reference. Therefore, you must first check that BallInPlay != null .


Additional offers:

  • Use EventArgs.Empty instead of new EventArgs() .

  • You can bypass the check for null if you initialized BallInPlay as follows:

    public event EventHandler BallInPlay = delegate { } ;

    This works because now there is always an "empty" handler method subscribed to this event. That way, you have the guarantee that the event delegate will no longer be null after initialization. (Some people may find this a bit ineffective.)

    You can always subscribe or unsubscribe event handlers with += or -= operators in the BallInPlay event; eg:

    ball.BallInPlay += (sender, e) => { /* react to the triggered event */ };

  • I think your onHit (or rather, onHit , if we adhere to the usual conventions found in the .NET world), the method should not be public , because it means the whole purpose of the events. Events are actually delegates, but with some additional restrictions. One such limitation is that only the class that defines the event can call ("trigger"). Delegates, on the other hand, can be called by anyone. Thus, if you make onHit public, thereby allowing anyone to trigger your event, you could pinpoint BallInPlay as a delegate, that is, without the keyword event .

  • The following is an implementation of the onHit method of triggering events << 2 โ†’ thread safe . Note that the local copy of the event handler delegate is used inside the method. This is done so that the event handler does not change (for example, by another thread) between checking for null and the call.


 protected virtual void OnHit() { EventHandler handler = BallInPlay; // use a local copy of the event if (handler != null) // for better thread-safety! { handler(this, EventArgs.Empty); } } 
+1
source
 BallInPlay += new EventHandler(myFunc); public void myFunc(object sender, EventArgs e) { MessageBox.Show("Woho \o/"); } 
0
source

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


All Articles