views:

39

answers:

3

What is a good (quick, efficient, etc.) way to store a snapshot of a collection for subsequent IsDirty checking?

Cheers,
Berryl

+3  A: 

It depends on what you want.

  • To create a snapshot of the collection you can just call IEnumerable<T>.ToList.
  • If you also want to create a snapshot of both the list and of each object in the list then you need to also make a separate copy of each object. How to best make a copy depends on the specific type of your collection. Some types have a Clone method. With others you can call a constructor. Some types cannot be easily copied.

Example:

List<Foo> snapshot = foos.Select(x => new Foo(x)).ToList();

To check if two IEnumerable<T>s are equal (i.e. check that there are no changes) you can use SequenceEqual. You will also need to specify an IEqualityComparer if your class doesn't implement Equals in the way you need.

If you want to have an efficient way to find a specific item in the snapshot from its id field then instead of a list you could use a Dictionary<K, V>. Call IEnumerable<T>.ToDictionary to create a dictionary from your collection.

Mark Byers
+1 for SequenceEqual
Kai Wang
A: 

Are you trying to check the collection or each individual member?

One approach is to use an ObservableCollection<T>. You can subscribe to events that are raised each time the collection is modified. The event args indicate item and the type of change.

Jay
The collection, as a default solution.
Berryl
+3  A: 

If you just want to save a snapshot and check if the size of your list changes (item added/removed)

var snapshot = new List<Foo>(list);

However if you are changing the items listed and want to check if the items have changed you'll have to clone each item. If you just stuff them into an other list the references should stay same.

var snapshot = list.Select(item => new Foo 
                                  { 
                                      Property1 = item.Property1,
                                      ... , 
                                      PropertyN = item.PropertyN 
                                   });

If you just want to see if the count of the list changes you can use the first version.

Maybe you have an Identifier on your objects which simplifies the solution to something like

var snapshot = list.Select(item => item.Id);

The list of IDs can be used to see if the contents changed. This pattern would help if your objects are big on memory usage, too.

However you may use an ObservableCollection<T> which has events to notify you on changes. This way you could track all changes to the collection (add/remove/replace).

Zebi