I\'m making a observable class. The Add methods works fine. But then I\'m trying to call the Remove() method I get this error:
\"Added item does not a
I tracked down the issue with Reflector and figured out the cause of this exception might refer to Equals
not returning true for actually equal objects in your list; or maybe operator ==
.
Are you sure the error is with the Remove
method? The error message and your source code indicate it is in the Add
method. Try using the correct index _list.Count - 1
in the constructor of NotifyCollectionChangedEventArgs
:
CollectionChanged(this, new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Add,
orderResponse, _list.Count - 1)
);
If I were to guess, I'd say that this line...
var item = _list.Where(
o => o.OrderDetail.TrayCode == orderResponse.OrderDetail.TrayCode)
.FirstOrDefault();
...because it calls FirstOrDefault()
, may be returning null
. Set a breakpoint and see what's actually going on.
To that end, why even do that query? Since you're passing in the object to be removed, why not simply do this:
int index = _list.IndexOf(item);
if (index >= 0)
this._list.RemoveAt(index);
//then pass item to your eventargs since it was the object removed.
Even better, since List<T>
has its own Remove(T object)
method:
this._list.Remove(item);
//this may throw an exception or not if the item is not in that collection,
// which is behavior you should probably retain
There is also a possible race condition in how you raise the CollectionChanged
event. In between checking for null
and raising it a subscriber could remove its delegate from the event. Here's an easy way to avoid that:
// initialize it with an empty lamda so it is never null
public event NotifyCollectionChangedEventHandler CollectionChanged = (o,e) => {};
Now you can just raise it and never need to check if it is null:
public void Add(OrderResponse orderResponse)
{
this._list.Add(orderResponse);
CollectionChanged(this,
new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add,
orderResponse, this._list.Count - 1));
}
This doesn't make it completely thread-safe, but it's an easy way of making sure raising the event won't throw a null reference exception.