tags:

views:

221

answers:

2

I have various ObservableCollections of different object types. I'd like to write a single method that will take a collection of any of these object types and return a new collection where each element is a deep copy of elements in the given collection. Here is an example for a specifc class

   private static ObservableCollection<PropertyValueRow> DeepCopy(ObservableCollection<PropertyValueRow> list)
   {
        ObservableCollection<PropertyValueRow> newList = new ObservableCollection<PropertyValueRow>();
        foreach (PropertyValueRow rec in list)
        {
            newList.Add((PropertyValueRow)rec.Clone());
        }
        return newList;
   }

How can I make this method generic for any class which implements ICloneable?

+6  A: 

You could do something like this:

private static ObservableCollection<T> DeepCopy<T>(ObservableCollection<T> list)
    where T : ICloneable
{
   ObservableCollection<T> newList = new ObservableCollection<T>();
   foreach (T rec in list)
   {
       newList.Add((T)rec.Clone());
   }
   return newList;
}

Note that you could make this more general by taking IEnumerable<T>, and LINQ makes it even easier:

private static ObservableCollection<T> DeepCopy<T>(IEnumerable<T> list)
    where T : ICloneable
{
   return new ObservableCollection<T>(list.Select(x => x.Clone()).Cast<T>());
}
Jon Skeet
I had tried that, but it doesn't seem to consider that a generic method. I get a "Constraints are not allowed on non-generic declarations" compiler error.
bwarner
Oops - I had a typo; you just need `<T>` at the end of the method name.
Jon Skeet
A: 
private static ObservableCollection<T> DeepCopy<T>(ObservableCollection<T> list) 
    where T : ICloneable 
{ 
   ObservableCollection<T> newList = new ObservableCollection<T>(); 
   foreach (T rec in list) 
   { 
       newList.Add((T)rec.Clone()); 
   } 
   return newList; 
} 
Hinek