Wednesday, October 6, 2010
I ran into a small problem in Silverlight today where I was quering a static list via linq and populating another custom list with the result.
When I proceeded to modify the values of the second list, the first list's values changed as well.
This is when I realised my mistake. LinQ never returns a copy/clone of a queried list, it returns the pointer/reference to the list.

So, the obvious solution was to clone/copy my object list and perform any changes I needed to on the cloned list.
The simplest approach to achieving this is to serialise our object list and deserialise it again. This will cause a copy of it be made in memory which we cast back to a new object list.

Here is how:

Firstly you will need to include Rockford Lhotka's Silverlight Serializer, you can download the class file here.
As Silverlight is running a slightly modified/minified version of .net, its missing a serialisation feature which this class file provides.

Next we write our object Clone method as follows:
    public static T Clone<T>(T obj)
      using (MemoryStream stream = new MemoryStream())
        SilverlightSerializer.Serialize(obj, stream);        
        stream.Position = 0;        
        return (T) SilverlightSerializer.Deserialize(stream);

And lastly here is an example of how to call the Clone method.

      // get records matching year and month
      var iEnumSales = dsc.Where(x => x.YearMonth.Year == year && x.YearMonth.Month == month).ToList();

var salesList = new DailySalesCollection(); // to prevent modifying the static collection later, we clone/copy the iEnumSales linq query results salesList.AddRange(ObjectHelper.Clone(iEnumSales));

Thats it for today.