I have a list List<MyClass>[,] myarraylist;
and it is filled.
I want to copy it to List<MyClass>[,] mycopy
then change mycopy
without changing myarraylist
.
What is the quickest way of doing this?
I have a list List<MyClass>[,] myarraylist;
and it is filled.
I want to copy it to List<MyClass>[,] mycopy
then change mycopy
without changing myarraylist
.
What is the quickest way of doing this?
It kind of depends on what you really want to do. You can easily clone the array:
List<MyClass> mcopy = new List<MyClass>[marraylist.GetUpperBound(0)+1,marraylist.GetUpperBound(1)+1];
for (int i = 0; i < marraylist.GetUpperBound(0); ++i)
{
for (int j = 0; j < marraylist.GetUpperBound(1); ++j)
{
mcopy[i,j] = marraylist[i,j];
}
}
Now, that gives you a copy of the array. But, mcopy[1,2]
has a reference to the same list as does marraylist[1,2]
. If you modify that list, that is if you were to write:
mcopy[1,2].Add(new MyClass(...));
Then that would also modify the list that is referenced in marraylist[1,2]
.
If you want to create copies of the lists, then the code in your inner loop has to be:
mcopy[i,j] = new List<MyClass>(marraylist[i,j]);
That creates a new list, so if you modify the list at mcopy[1,2]
, you don't modify the list in the original array.
But that might not be what you want, either. Because although mcopy[1,2]
contains a different list than marraylist[1,2]
, the lists have the same contents. So if you wrote mcopy[1,2][1].SomeProperty = 42;
, then you'll also modify the contents of the object at marraylist[1,2][1]
, because they're the same object.
If you want to copies of the lists and copies of the objects, then your inner loop code becomes:
mcopy[i,j] = marraylist[i,j].Select(m => new MyClass(/* create from m */)).ToList();
The /* create from m */
comment means that you either pass m
to the copy constructor (if you have one), or pass the individual parameters, or if you have a clone method on the class you'll use that. Somehow you want to make a deep copy of the MyClass
instance.
Yes, it's complicated. The word "copy" is quite overloaded here, and how you proceed depends entirely on what definition of "copy" you're using. Do you want to make a copy of the array (just copy the references), the array's contents (create new lists with the same objects), or the lists' contents (create new lists with new objects that contain the same data)?
If MyClass has a copy constructor:
var newList = new List<MyClass>[oldList.GetLength(0), oldList.GetLength(1)];
for (int i = 0; i < oldList.GetLength(0); i++)
for (int j = 0; j < oldList.GetLength(1); j++)
newList[i, j] = oldList[i, j].Select(x => new MyClass(x)).ToList();
If it doesn't have a copy constructor, and you can't add one, you will have to write your own function to make a copy of MyClass.
newList[i, j] = oldList[i, j].Select(x => CloneMyClass(x)).ToList();
This may work. It is an extension method to 2D IEnumerables. That means it can be used with anything that implements the IEnumerable
interface, as long as your class T
implements ICloneable
.
public static IEnumerable<IEnumerable<T>> Clone<T>(this IEnumerable<IEnumerable<T>> twoDList) where T : ICloneable
{
if (twoDList != null)
{
List<List<T>> result = new List<List<T>>();
for (int i = 0; i < twoDList.Count(); i++)
{
List<T> aList = new List<T>();
for (int j = 0; j < twoDList.ElementAt(i).Count(); j++)
{
aList.Add(twoDList.ElementAt(i).ElementAt(j));
}
result.Add(aList);
}
return result;
}
else
{
return null;
}
}
It should also work with jagged 2D structures that implement IEnumerable
.
Example Usage follows:
List<List<MyClass>> cloned = original2DStructure.Clone();
Help on making your class implement ICloneable
could be found here.