1

This is very similar to the question but specific to Lists.

How to trigger event when a variable's value is changed?

Every time my list is modified I want to run a method.

I assumed using a property and putting a method within 'set' would be the correct way to approach this. I started with something like this

public class Stuff
{
   private List<Things> _myThings;

   public List<Things> MyThings
    {
        get 
        {
            return _myThings;       
        }
        private set
        {
            _myThings= value;
            runWhenListIsChanged();
        }
    }
}

However, when I use a command like 'RemoveAt' or 'RemoveRange'

public class StuffChanger
{
    Stuff.MyThings.RemoveAt(5);
}

It goes straight into the 'get' property and the list is changed.

I wrongfully presumed it would use set (as its changing the list) but that's not the case. When debugging (using the 'step into' tool in Visual Studio) I noticed the List can be modified by using the 'get' accessor.

In this particular case, I don't want to have a method being called every time the list is read by something, as this could get performance heavy or cause a stack overflow. So that isn't an option.

I'd be very grateful if anyone has any tips or code suggestions! Thanks very much.

Community
  • 1
  • 1
Jim
  • 761
  • 3
  • 10
  • 32
  • You could use an `ObservableCollection` instead and register the `CollectionChangedEvent`. It will fire on any manipulation of the collection. – Tom Wuyts Jan 06 '16 at 12:12

1 Answers1

2

As you have observed, the code you wrote to manipulate the list does in fact not set a new list into the property.

Instead, this code:

Stuff.MyThings.RemoveAt(5);

can be thought of as similar to this:

var list = Stuff.MyThings;
list.RemoveAt(5);

As such, it reads the list out of the getter, and then directly manipulates the list itself.

To get notifications when the list itself is changing, you will need to use something other than List<T> since this type does not have any functionality to support that requirement.

A good candidate would be ObservableCollection<T> and you would hook up an event handler to the CollectionChanged event.

Please note that this will only observe changes to the list, and not to the elements in the list. If you add or remove an item from the list, you will get notifications but if you execute code like this:

MyStuff.MyThings[0].SomeProperty = SomeNewValue;

then you will not get any notifications from the list itself. You will have to implement something like INotifyPropertyChanged on the element types, and hook up event handlers to that to get those notifications.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
  • Thank you Lasse. I should of added that I'm using Unity 5.3, which doesn't have .net 4.5+ (I believe) so I may have to add my own Observable Collection script. – Jim Jan 06 '16 at 12:45