cincyreds Posted April 24, 2005 Posted April 24, 2005 (edited) I have a collection (collection "A") on which I need to do some processing. The processing will actually modify "A" by deleting entries. After the processing is over, I want to restore the collection to its original state. So, before the processing starts I need to copy collection "A" to a temporary collection (let's call it "Temp"). Then do the processing which basically destroys collection "A" After processing is over, copy "Temp" back to "A". The problem with just using: Dim Temp as new Collection Temp = A <do some processing> A = Temp is that anything that happens to A during processing is reflected in Temp, so Temp gets destroyed too. I've tried putting the processing into a separate function and passing collection "A" ByVal to that function, then restoring upon completion. No go. It seems passing a collection ByVal has no effect - the collection is STILL modified. What's the quickest way to copy a collection "ByVal " for lack of a better description? Thanks, Dean Edited April 24, 2005 by cincyreds Quote
mskeel Posted April 25, 2005 Posted April 25, 2005 Major advantage of serialization is that you can get a deep copy of your collection. Disadvantage is that in order for it to work all objects in your collection will also have to be serializable. This thread will probably be useful to you. Quote
Leaders snarfblam Posted April 25, 2005 Leaders Posted April 25, 2005 This is my recommendation: Create an array (of whatever type of object the collection holds) and use the collections CopyTo method to create a copy of the collection in an array. When you need to restore the collection, call the collections Clear method, the call the collections AddRange method, passing your array. When you pass any reference type (i.e. any class) as a parameter, you are passing a pointer: a memory address. When you pass it ByVal you are passing a copy of the pointer. When you pass it ByRef, you are passing the actual reference. Either way, the function being called gets the address of the object and can modify it. The only difference is if you pass the object as ByRef, since you are passing the actual reference the funtion being called can change what the original reference points to. My point is, you need to create a copy of a class (or copy of the data it represents) if you want to pass it to a function. Quote [sIGPIC]e[/sIGPIC]
cincyreds Posted April 25, 2005 Author Posted April 25, 2005 Create an array (of whatever type of object the collection holds) and use the collections CopyTo method to create a copy of the collection in an array. When you need to restore the collection, call the collections Clear method, the call the collections AddRange method, passing your array. Thanks for for the advice and great explanation. I'll give it a try. :) Quote
mskeel Posted April 25, 2005 Posted April 25, 2005 My point is' date=' you need to create a copy of a class (or copy of the data it represents) if you want to pass it to a function.[/quote'] True. But be careful of shallow copies which almost all CopyTo methods impliment. If you hold howegrown objects in your collection copying the collection will only copy the references, the pointers. This means if you change your copy you will change the original as well whether you pass it ByRef or ByVal. The pointers point to the same memory in both the copy and the original. So what good is a shallow copy then? I don't really know. They always seem to cause more harm than good. Quote
Leaders snarfblam Posted April 25, 2005 Leaders Posted April 25, 2005 That is something I should have pointed out. Suppose you want to present the user (or recieving function) a filtered list, where they can simply select certain items. Or If you wanted to use the collection in a read-only manner. There is no disadvantage to having a shallow copy here. There can even be an advantage to having shallow copies of collections. Suppose you want to present a filtered collection, allow the recipient to modifty the filterd collection, and have those changes reflected back in the original collection. Easiest done with a shallow copy of the collection. I have done this with listviews in the past: create a shallow copy, filter the list by removing items, and when the user wants to remove the filter, clear the list and add the copied list back. That way, when the filter is removed, since the copy of the list was shallow, any changes they made wont be undone. And of course there are the things you need to watch out for. You can not add a listview item to more than one listview at a time, so you would need to create a deep copy in such a case (same applies to many windows forms collections). And if you don't want the original collection to be modified, you would need to create a deep copy. Quote [sIGPIC]e[/sIGPIC]
HJB417 Posted April 26, 2005 Posted April 26, 2005 You'll need to do a deep copy of the original/target collection. How do to that depends on what interfaces the collection extend and what methods are available. Using the ArrayList constructor that takes an ICollection as a parameter will perform a deep copy. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.