Cloning List<T> in Silverlight

invidia

Platinum Member
Oct 8, 2006
2,151
1
0
This is under Silverlight 3, so a number of .NET options are unavailable, like ICloneable/Clone method. I've been stuck for days at trying to clone a List of objects. I already spent hours Googling and asking on the ASP.NET forums and SL forums.

Here is a pseudocode of what I'm trying to do:

Code:
List<objectType> originalList = ................
List<objectType> newList = new List<objectType>(originalList);

newList[0].name = "Bob";

Apparently newList is just a reference to the original list. The first item's name property will also be changed to "Bob". I need a deep clone of the list. A copy, not a reference. But Silverlight is lacking a number of methods, such as list<T>.Clone, ICloneable, etc for me to do that. What other solutions are there?
 

MSCoder610

Senior member
Aug 17, 2004
831
0
71
Is objectType your own type? If so, I don't see why you couldn't define your own Clone/ Copy method on it, then do
Code:
List<objectType> originalList = ................
List<objectType> newList = new List<objectType>();
foreach(objectType myObj in originalList)
{
  newList.Add(myObj.Clone());
}

Or something like that.
 

Cogman

Lifer
Sep 19, 2000
10,286
147
106
a for loop. I'm not familiar with silverlight's syntax, but it looks c'esq so I'm going to say something like

Code:
List<objectType> origionalList = ..............
List<objectType> newList;
for (int i = 0; i < origionalList.size(); ++i)
{
    // This might not work, as I don't know how the list sizes work, you may have to define somehow that newList is the size of origionalList.
    newList[i] = origionalList[i];

    OR

    // I don't know if there is an add function, but there should be something like it
    newList.add(origionalList[i]);
}

Most likely what is happening in the background is that the newList is just getting all the datamembers from origionalList (IE a bit-for-bit copy), One of the data members of the originalList is a pointer to the array, or first element, in the list. NewList just grabs that pointer and does not actually create each data element like you would want.
 

invidia

Platinum Member
Oct 8, 2006
2,151
1
0
Is objectType your own type? If so, I don't see why you couldn't define your own Clone/ Copy method on it, then do
Code:
List<objectType> originalList = ................
List<objectType> newList = new List<objectType>();
foreach(objectType myObj in originalList)
{
  newList.Add(myObj.Clone());
}
Or something like that.

Clone is part if ICloneable, which is not available in Silverlight.

a for loop. I'm not familiar with silverlight's syntax, but it looks c'esq so I'm going to say something like

Code:
List<objectType> origionalList = ..............
List<objectType> newList;
for (int i = 0; i < origionalList.size(); ++i)
{
    // This might not work, as I don't know how the list sizes work, you may have to define somehow that newList is the size of origionalList.
    newList[i] = origionalList[i];

    OR

    // I don't know if there is an add function, but there should be something like it
    newList.add(origionalList[i]);
}
Most likely what is happening in the background is that the newList is just getting all the datamembers from origionalList (IE a bit-for-bit copy), One of the data members of the originalList is a pointer to the array, or first element, in the list. NewList just grabs that pointer and does not actually create each data element like you would want.

Silverlight is C# and XAML. It's basically the same as programming in ASP.NET with C#, except your XAML pages are the equivalent to ASP pages. I tried what you do above and they are still references to the original list. Changing an item in newList still affected originalList.
 

Crusty

Lifer
Sep 30, 2001
12,684
2
81
It doesn't matter if you don't implement the ICloneable interface. Just add a Clone() method to your class and call that in a foreach to build your new list. I think you're trying to make it more complicated than it really is.

Your method doesn't even have to be called Clone(), you can call it MakeACopy() if you wanted.

Another way is to create a Copy Constructor, a constructor that takes objectType as a parameter and copies those values into the new instance being created.

Then your loop would look like
Code:
foreach(objectType myObj in originalList)
{
  newList.Add(new objectType(myObj);
}
 

invidia

Platinum Member
Oct 8, 2006
2,151
1
0
It doesn't matter if you don't implement the ICloneable interface. Just add a Clone() method to your class and call that in a foreach to build your new list. I think you're trying to make it more complicated than it really is.

Your method doesn't even have to be called Clone(), you can call it MakeACopy() if you wanted.

Another way is to create a Copy Constructor, a constructor that takes objectType as a parameter and copies those values into the new instance being created.

Then your loop would look like
Code:
foreach(objectType myObj in originalList)
{
  newList.Add(new objectType(myObj);
}

Ok, I see what you mean. I'm getting confused with .NET's own Clone() that's part of the ICloneable. Thanks
 

JasonCoder

Golden Member
Feb 23, 2005
1,893
1
81
Just remember to not only clone the list, but the objects in the list as well. Also might want to lock the list so that you don't end up adding to it whilst enumerating the items.
 

Markbnj

Elite Member <br>Moderator Emeritus
Moderator
Sep 16, 2005
15,682
14
81
www.markbetz.net
Just remember to not only clone the list, but the objects in the list as well. Also might want to lock the list so that you don't end up adding to it whilst enumerating the items.

This is really the key point. It's trivial to loop through a list and insert the items into another collection, but they will still be references to the same items. You need to copy the individual items as you walk the first list, and insert the copies into the second list.
 

boran

Golden Member
Jun 17, 2001
1,526
0
76
I guess nothing prevents you from declaring an own Iclonable interface ?
Because right now you are stuck at x levels deep (where x is the amount of for loops you write) if you make an Iclonable interface you could recurse and use that. Offcourse I do not have a lot of SL experience, so this might not work.

Greetings
 

Markbnj

Elite Member <br>Moderator Emeritus
Moderator
Sep 16, 2005
15,682
14
81
www.markbetz.net
I guess nothing prevents you from declaring an own Iclonable interface ?
Because right now you are stuck at x levels deep (where x is the amount of for loops you write) if you make an Iclonable interface you could recurse and use that. Offcourse I do not have a lot of SL experience, so this might not work.

Greetings

Yeah, the issue of how deep or shallow the copy needs to be is also fundamental. If the list contains objects that hold references to other objects then of course those need to be deep-copied, or the design has to account for the fact that they won't be. If that's the case I would suggest there are larger design issues at work.