Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Least cpu intensive method of checking if a list has changed in c#

Tags:

c#

list

I have a function that is to be called if a list has changed since it was last called, what would be the best way of implementing this?

ex:

List<A> OurList = new List<A>();
private void Update()
{
    Boolean Changed = //?    
    if(Changed) CheckList(OurList);
}

I would have assumed make a variable to store the old list and compare, but how would I update the old list to the new list without copying it all out? (If I do an assign, it will update the "old list" too)

like image 737
Blam Avatar asked Sep 02 '10 19:09

Blam


4 Answers

Use an ObservableCollection<T> instead of a List, then subscribe to the CollectionChanged event.

This way, you will be told when the list is changed instead of having to scan the data to figure out what happened after the fact.

like image 118
dthorpe Avatar answered Sep 21 '22 17:09

dthorpe


The most efficient way would be to wrap the List<> in your own class and have all the mutating methods (Add, Remove) set a boolean flag.

Your Method can then just look at that flag and reset it.

like image 27
Henk Holterman Avatar answered Sep 20 '22 17:09

Henk Holterman


If you're using .NET 4.0, you could use the ObservableCollection class. (prior to 4.0, you would need to reference WPF).

Once you create your list, just add a handler to the CollectionChanged event.

like image 5
Robaticus Avatar answered Sep 19 '22 17:09

Robaticus


Your best bet would be to use an ObservableCollection<T> or BindingList<T> to get push notification of a change. You could also subclass Collection<T> if you want any custom behaviour.

To answer your question as asked (except for the cpu-intensive bit), you can use an existing feature of List<T>: it maintains its own version internally so that it can throw if the collection has changed during enumeration.

This is based on analyzing code from reflector. It is not part of any contract, so it is liable to break at any time. It may also not work in a partial-trust environment. Please use with care:

public static int GetVersion<T>(this List<T> list)
{
    return (int)list.GetType()
                    .GetField("_version", BindingFlags.Instance | BindingFlags.NonPublic)
                    .GetValue(list);
}

...

private int _lastCheckedVersion = 0;

private void Update()
{
    int currentVersion = ourList.GetVersion();

    if(currentVersion != _lastCheckedVersion) CheckList(ourList);

    _lastCheckedVersion = currentVersion;
}
like image 2
Ani Avatar answered Sep 20 '22 17:09

Ani