Jeff and .NET

The .NET musings of Jeff Putz

Sponsors

News

My Sites

How do I really copy a List<T> object?

OK, color me annoyed. I want to copy a List<T> object because I want to manipulate the junk in it. The junk is in the ASP.NET cache, so if I alter it, it gets changed and the change is reflected on the next request.

For example... right now I have

List<Foo> list = Foo.GetFromCache();
list[0].MyString = "yo";


As you would expect, that MyString property is going to be "yo" next time I get it. I tried using List<T>.CopyTo() to copy it to an array, but that array is still a reference to the original.

It's gotta be easier... right?
Posted: Nov 21 2005, 09:48 PM by Jeff | with 12 comment(s)
Filed under:

Comments

karl said:

I guess the same way you do an ArrayList, serialize the object and then deserialize it, try:

BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();

bf.Serialize(ms, strings);
ms.Seek(0, SeekOrigin.Begin);
List<string> copy = (List<string>)bf.Deserialize(ms) ;
ms.Close();

Karl
# November 21, 2005 10:16 PM

Dean Harding said:

You have to either serialize then deserialize, or manually call ICloneable.Clone on each element as you construct a new List. Depending on the types involved, one may be faster than the other.

In either case, if the type Foo isn't marked with the SerializableAttribute or it doesn't implement ICloneable (and you don't own Foo so can't implement it yourself), then you're pretty screwed, I would think...
# November 21, 2005 10:38 PM

Jeff said:

Is there some good reason for this omission from the framework? My Java buddy was telling me you can call a Copy() method on practically anything to do this.
# November 21, 2005 10:49 PM

Dean Harding said:

Well, I guess it's the same reason that they require you to implement ICloneable yourself rather than doing it automatically. Technically, there's no reason why they couldn't have included a 'Deep-copy' directly into the framework, but they decided to make it manual.

Also, you could write your own List which supported a deep-copy clone, something like this:

class CloneableList<T : ICloneable> : List<T>, ICloneable
{
public object Clone()
{
CloneableList<T> clone = new CloneableList<T>(this.Count);
foreach(T t in this)
{
clone.Add(((ICloneable) t).Clone());
}
return clone;
}
}

That's just off the top of my head, so I might have got something wrong, but that's the basic idea...
# November 21, 2005 10:55 PM

Frans Bouma said:

... and in the object to clone, call base.MemberwiseClone() to get a deep copy.
# November 22, 2005 4:10 AM

Johnny said:

Or you may use something like:

yourList.ForEach(delegate(string s) { yourListTwo.Add(s); });

# February 3, 2008 1:25 PM

James said:

Could try this one to make a real copy of a list-object.

List<MyType> list_1= Common.FillMyListWithMyTypeObjects();

List<MyType> list_2 = new List<MyType>();

list.InsertRange(0, list_1);

So you don't have a object which is linked to the same refernce, it's a complete new object!

Hope that works

# May 29, 2008 3:59 AM

x1 said:

Very useful post about using serialization for cloning objects

# October 26, 2008 4:00 PM

hitchhiker said:

what about

l1.Categories.ForEach(l2.Add);

# March 6, 2009 9:46 AM

Harsh G said:

Check for overloaded constructors for List<T>. One of them accepts IEnumerable(T) as parameter and copies the content of this list to another.

//Original List

List<int> orgList = new List<int>();

...

//New List

List<int> newList = new List<int>(orgList);

Hope I am correct. This is my first reply to any blog!!!

# July 9, 2009 8:10 AM

Rob said:

The problem with using

List<T> newList = new List<T>(orgList);

Is that it works only when T is a value type such as int, bool, and so on, it does not work with reference types.  You just have a new list that contains the SAME references as the old list and if you change any property of one of the list objects, it will change in BOTH lists.  In the end, you just have to create NEW objects of type T, do a deep copy of the object and add it to a new list.

Rob

# February 17, 2010 3:48 PM

Raul said:

"Or you may use something like:

yourList.ForEach(delegate(string s) { yourListTwo.Add(s); });"

didnt work either...

im trying to clono an object lista, but any change apply to the new one, affects the old one...

is there any solution for framework 2.0??

# February 2, 2011 8:33 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)