Why is my event throwing a null error? - c#

For some reason my event is throwing a null error. I don't see anything wrong.
here is the event
public delegate void connectionSuccess(bool success);
public event connectionSuccess Connection;
then in a function i have this witch throws the null error
Connection(true);
Edit* function in another class that calls the connection function
Server.Connection += onConnection;
Server.startConnection();

If it is not connected, it is null.
Try this instead:
var h = Connection;
if ( h!=null )
{
h(true);
}
I'm assigning to a (local) variable first in order to overcome multi-threading scenarios where there are modifications between checking for null and calling.
I.e. the following would not be thread-safe:
if ( Connection!=null )
{
Connection(true); // Here, could already be null, again.
}

You need to check and make sure something is actually subscribed to the event before you invoke it.
if(Connection != null)
Connection(true);

Because you have no subscribers yet. When an event has no subscribers it becomes null. You have two options to solve this (I prefer the second).
Option 1:
if (Connection != null)
Connection(true);
Option 2:
public event connectionSuccess Connection = delegate { };

You are getting the error because a null reference exception will be thrown if there is the null delegate reference! So, it is necessary to check the delegate reference.
It is a good practice to create an event invocator - helper method. It simplifies calling the event handlers.
For example, let's take a look at Book class which implements INotifyPropertyChanged interface:
class Book : INotifyPropertyChanged
{
private string _name;
public string Name
{
get { return _name; }
set
{
if (_name == value)
return;
_name = value;
OnPropertyChanged("Name");
}
}
#region Implementation of INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Event invocator.
/// </summary>
/// <param name="propertyName">Property name.</param>
private void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
More detailed information about the implementation of event invocators is here: Events and Races.

You should check the initialization of your objects. While your code does make it look like everything is in the same class, I'm not sure why you would go through the headache of creating events instead of just calling the method.
HOWEVER, if your raising the event in one class and attempting to handle it in another, you may run into the same thing that I did. Let me explain...
MDIParent - Contains the instantiation code for the child form. Also has the code to wire the event handler of the child to the code on the MDIParent.
Form x = new MyTestForm();
x.OnMyEvent += this.HandleEvent(myEventArgs);
MDIChild - Contains the code that we use to create the event and actually trigger it.
public MyTestForm()
{
public event EventHappened MyEventHandler;
}
Later in the code, we actually raise the event.
MyEventHandler(new MyEventArgs(this, "some message");
The problem that I was having with all of my event handlers, which we were using to update a StatusBar, was that the wiring up of the event wasn't happening until the form was completely initialized. This means that all of the work in setting up the form was complete by the time we actually wired the event TO something!
How did I get around this, you ask? Well, I moved all of the initialization code into a separate method and out of the constructor. We call the constructor to create an instance of the form, wire the events up, and THEN run through all of the form's creation tasks.
Hope that this helps someone! I spent days trying to figure out why my events were null when I could plainly see that they were assigned!

Related

Why can't I raise or call event if I have overloaded add and remove in C#

While copying code for RelayCommand from Josh Smith article I copied following code
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
Then after reading this answer on SO I also copied in my class following code from DelegateCommand class of Prism.
protected void NotifyCanExecuteChanged()
{
if (CanExecuteChanged != null)
{
CanExecuteChanged(this, EventArgs.Empty);
}
}
But his gives me an error in NotifyCanExecuteChanged method
The event 'CanExecuteChanged' can only appear on the left hand side of += or -=
This error is not coming if I remove the add and remove overload from event. Can someone please help me understand the reason behind this?
With a field-like event (which is the name for the simple form without add/remove, then when you do if(CanExecuteChanged != null) or CanExecuteChanged(this, ...), the CanExecuteChanged is referring to the backing field, which is a delegate field of type EventHandler. You can invoke a delegate field. However, that is not the case in your example, because there is no obvious thing to invoke. There certainly isn't a local field, and the forwarded event (CommandManaged.RequerySuggested) does not intrinsically expose any "invoke" capability.
Basically, for that to work you would need access to an invoke mechanism. Most commonly, I would expect that to take the form of:
CommandManager.OnRequerySuggested();
but if there is a method that invokes this event (and there doesn't need to be), it could be called anything.
(the On* is a common pattern for a "raise this event" API, doubly-so if it is polymorphic)
I think you want CommandManager.InvalidateRequerySuggested. It forces the RequerySuggested event to be raised.
It seems like your class inherits from the class where event is declared. Event can be directly raised only in the base class, not in inherited class.
If you want to raise it in inherited class, write the following method in your base and call it from inherited class:
protected void RaiseMyEvent()
{
if (MyEvent != null)
{
MuEvent(this, args)
}
}

.net Event Confusion

I have a data structure class that is a child of a larger data/state class.
The inner data structure fires an event when the contained data changes. This event is consumed by the larger data/state class. The data/state class then fires its own event so that it may pass additional information along to the next event handler.
Public class Data
{
//properties and objects go here
public int Count
{
get { return _count; }
internal set
{
//if the count grew simply set _count
if (value != _oldCount)
{
_oldCount = _count;
_count = value;
}
//if the count shrank then set the count and trigger an event if the count is under 100
else
{
_oldCount = _count;
_count = value;
if (_count < 100)
{
CountChanged(this, new EventArgs());
}
}
}
}
public event EventHandler CountChanged;
}
The above event is consumed by this event handler
Data.CountChanged += new EventHandler(DataCountChanged);
private void DataCountChanged(object sender, EventArgs e)
{
DataRemoved(this, e); //Handle the old event and trigger a new event to pass along more information
}
public event EventHandler DataRemoved;
Finally the second event should be handled by another event handler to do some work. Unfortunately the call to trigger the second event fails with a NullReferenceException more often than not. Why?
----EDIT----
I understand that checking for Null will prevent the exception. The confusion is why this event is Null in the first place =D
You should always raise events using the following pattern to avoid null references and threading issues:
private void DataCountChanged(object sender, EventArgs e)
{
var dr = DataRemoved;
if (dr != null)
{
dr(this, e);
}
}
The reason the handler is null is that it should be viewed as a special collection of delegates. When the collection is empty the delegate has a null value. When you attach one or more handlers the collection is no longer empty and thus is no longer null.
if(DataRemoved != null && DataRemoved.GetInvocationList().Length > 0)
{
}
Assigning an empty delegate to your events may not be such a good design practice. Events are essentially delegates which are like function pointers. In other words, they are just like other reference members in your class. Unless you assign them a value or subscribe to them, they will be and should be null.
The null reference exception you get is for the same reason as declaring private MyClass; and then trying to use it before it has been assigned a value.
When you subscribe to an event, you are essentially telling the event which function to call. If your event does not have at least one such function pointer, it would not be in existence (NULL).
There is a trick to avoid the null check:
Just initialize your event as follows:
public event YourDelegate MyEvent = delegate { };
This way you do not need to check for nulls just call the event as usual:
this.MyEvent("Hi there!");
Edited
To clarify:
Declaring an event like this:
public event Action MyEvent;
It's translated automatically to:
private Action myEvent;
public event Action MyEvent
{
add
{
this.myEvent += value;
}
remove
{
this.myEvent -= value;
}
}
Therefore initializing an event like this:
public event Action MyEvent = delegate { };
It's safe because external code can not assign a null to the event itself.
You can however, assign null to the event inside the class it was declares but what really is happening is that, you are assigning null to the private delegate used by the event.
Source: Jon Skeet, C# In Depth, Events

Handling an event that might not have any subscriber

If a class fires events in its methods, the class does not have to know what or who subscribes its events. It is not also important if there is any subscriber.
In the code below, if there is not any subscriber to OnTrigger event, an exception occures.
public class EventTrigger
{
public static void Main(string[] args)
{
(new EventTrigger()).Trigger();
}
public delegate void Delegate1();
public event Delegate1 OnTrigger;
void Trigger()
{
OnTrigger();
}
}
I can call the event like this;
if (OnTrigger != null)
{
OnTrigger();
}
But it seems weird to me, because the triggerer does not have to know about subscription.
My question is:
Do I have to check if the event reference is null whenever I use it.
If you initialize OnTrigger then you wont have to do the check.
e.g.
public event Action OnTrigger = delegate { };
Yes ´delegate { }´ instantiates a new object, which is why this allows you to omit the ´null´ check.
´delegate { }´ returns nothing, so if you want it to return a string (which you need if Delegate1 returns a string) then you simply add ´return "";´ e.g.:
public event Action OnTrigger = delegate { return string.Empty; };
One I should add is that it's bad practice to do this in order to avoid a null check, as it's a lazy mans hack. Some code can still set the event to null, ´OnTrigger = null´ will break your code. And when it comes to (de)serialization it wont work at all.
The triggerer doesn't have to know about the individual subscribers, but it does need to know about subscription. You have to either do the null check every time or use the work-around Simon suggested.

INotifyPropertyChange ~ PropertyChanged not firing when property is a collection and a new item is added to the collection

I have a class that implements the INotifyPropertyChanged interface. Some of the properties of the class are of type List. For example:
public List<string> Answers
{
get { return _answers; }
set
{
_answers = value;
onPropertyChanged("Answers")
}
}
...
private void onPropertyChanged(string propertyName)
{
if(this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
If I assign a new List<string> to Answer, then the PropertyChanged event fires as expected; but if I add a string string to the Answer list using the List Add method, then PropertyChanged event doesn't fire.
I was considering adding an AddAnswer() method to my class, which would handle calling the lists's Add method and would call onPropertyChanged() from there, but is that the right way to do it? Is there a more elegant way of doing it?
Cheers,
KT
You should expose an ObservableCollection<string>, which implements the INotifyCollectionChange interface to raise its own change events.
You should also remove the property setter; Collection properties should be read only.
You should not raise the PropertyChanged event when the contents of the collection change.
Ok I just finally experienced this issue, and there are NO complete answers on the Internet afaikt, so here is the missing piece that no one mentions (maybe because the assume that we are not complete morons and have NOT deleted the default constructor, or have alteast extended the default constructor) anyhow:
Make certain that you DID NOT delete the InitializeComponent(); call in the constructor of your View.
Without this call BEFORE you set DataContext of the view, NotifyPropertyChanged Event will ALWAYS BE NULL. I spent about 2 hours trying to figure out what was different between two different MVVM userControls. I guess my mind is so used to seeing InitializeComponent(); that it did not register that it was missing. I added that back and viola!
Hope This Helps Other Dummies Like Me!
Cheers,
Code Warrior Malo
It's not firing because the collection reference isn't changing, just the contents. You'd need the collection's Add() method to fire the event to be able to see it.
have a look at System.Collections.ObjectModel.ObservableCollection. http://msdn.microsoft.com/en-us/library/ms668604.aspx
It can be used like a List but has events built in for when its contents change.
ObservableCollection is your answer. If you want to fire on collection property changes, you'll need to implement INotifyPropertyChanged for each of the properties you'd like to track.
You should add an event listener to your _answers collection. Unfortunately, List<T> doesn't provide such an event.
As a suggestion, manage _answers as an ObservableCollection<string>, and properly attach/detach an event handler for the CollectionChanged event, as follows:
public ObservableCollection<string> Answers
{
get { return _answers; }
set
{
// Detach the event handler from current instance, if any:
if (_answers != null)
{
_answers.CollectionChanged -= _answers_CollectionChanged;
}
_answers = value;
// Attatach the event handler to the new instance, if any:
if (_answers != null)
{
_answers.CollectionChanged += _answers_CollectionChanged;
}
// Notify that the 'Answers' property has changed:
onPropertyChanged("Answers");
}
}
private void _answers_CollectionChanged(object sender,
NotifyCollectionChangedEventArgs e)
{
onPropertyChanged("Answers");
}

Why must someone be subscribed for an event to occur?

Some text before the code so that the question summary isn't mangled.
class Tree
{
public event EventHandler MadeSound;
public void Fall() { MadeSound(this, new EventArgs()); }
static void Main(string[] args)
{
Tree oaky = new Tree();
oaky.Fall();
}
}
I haven't used events much in C#, but the fact that this would cause a NullRefEx seems weird. The EventHandler reference is considered null because it currently has no subsribers - but that doesn't mean that the event hasn't occurred, does it?
EventHandlers are differentiated from standard delegates by the event keyword. Why didn't the language designers set them up to fire silently in to the void when they have no subscribers? (I gather you can do this manually by explicitly adding an empty delegate).
Well, the canonical form is:
void OnMadeSound()
{
if (MadeSound != null)
{
MadeSound(this, new EventArgs());
}
}
public void Fall() { OnMadeSound(); }
which is very slightly faster that calling an empty delegate, so speed won out over programming convenience.
Another good way I've seen to get around this, without having to remember to check for null:
class Tree
{
public event EventHandler MadeSound = delegate {};
public void Fall() { MadeSound(this, new EventArgs()); }
static void Main(string[] args)
{
Tree oaky = new Tree();
oaky.Fall();
}
}
Note the anonymous delegate - probably a slight performance hit, so you have to figure out which method (check for null, or empty delegate) works best in your situation.
The recommended pattern is (.net 2.0+)
public class MyClass
{
public event EventHandler<EventArgs> MyEvent; // the event
// protected to allow subclasses to override what happens when event raised.
protected virtual void OnMyEvent(object sender, EventArgs e)
{
// prevent race condition by copying reference locally
EventHandler<EventArgs> localHandler = MyEvent;
if (localHandler != null)
{
localHandler(sender, e);
}
}
public void SomethingThatGeneratesEvent()
{
OnMyEvent(this, EventArgs.Empty);
}
}
I see a lot of recommendations for an empty delegate{} in an initializer, but I totally disagree with it. If you follow the above pattern you only check the event != null in one place. The empty delegate{} initializer is a waste because it's an extra call per event, it wastes memory, and it still can fail if MyEvent was set to null elsewhere in my class.
* If your class is sealed, you wouldn't make OnMyEvent() virtual.
You need to understand what your event declaration is actually doing. It's declaring both an event and a variable, When you refer to it within the class, you're just referring to the variable, which will be null when there are no subscribers.
Very Zen, eh?
You have to test for null when you want to raise an event:
protected void OnMyEvent()
{
if (this.MyEvent != null) this.MyEvent(this, EventArgs.Empty);
}
It would be nice if you didn't have to bother with this, but them's the breaks.
James provided a good technical reasoning, I would also like to add that I have seen people use this an advantage, if no subscribers are listening to an event, they will take action to log it in the code or something similar. A simpl example, but fitting in this context.
What is the point of raising an event if no one is listening? Technically, its just how C# chose to implement it.
In C#, an event is a delegate with some special feathers. A delegate in this case can be viewed as a linked list of function pointers (to handler methods of subscribers). When you 'fire the event' each function pointer is invoked in turn. Initially the delegate is a null object like anything else. When you do a += for the first subscribe action, Delegate.Combine is called which instantiates the list. (Calling null.Invoke() throws the null exception - when the event is fired.)
If you still feel that "it must not be", use a helper class EventsHelper as mentioned here with old and improved 'defensive event publishing' http://weblogs.asp.net/rosherove/articles/DefensiveEventPublishing.aspx
Using an extension method would be helpful in this scenario.
public static class EventExtension
{
public static void RaiseEvent<T>(this EventHandler<T> handler, object obj, T args) where T : EventArgs
{
if (handler != null)
{
handler(obj, args);
}
}
}
It can then be used like below.
public event EventHandler<YourEventArgs> YourEvent;
...
YourEvent.RaiseEvent(this, new YourEventArgs());
Thank you for the responses. I do understand why the NullReferenceException happens and how to get around it.
Gishu said
What is the point of raising an event if no one is listening?
Well, maybe it's a terminology thing. The appeal of an "event" system seems to me that all the responsibility of the fallout of the event that took place should be on the watchers and not the performer.
Perhaps a better thing to ask is: If a delegate field is declared with the event keyword in front of it, why doesn't the compiler translate all instances of:
MadeSound(this, EventArgs.Empty)
to
if (MadeSound != null) { MadeSound(this, EventArgs.Empty); }
behind the scenes in the same manner that other syntax shortcuts are? The number of boilerplate OnSomeEvent null checking methods that people have to write manually must be colossal.

Categories

Resources