当我尝试使用.ToArray()创建一个包含深层副本的数组时,我遇到了一个问题。
这是我的测试类:
public class MyClass
{
public Color Color1;
public MyClass(Color color)
{
this.Color1 = color;
}
}
这是我用来执行List
的ToArray()的代码List<MyClass> listColors = new List<MyClass>();
listColors.Add(new MyClass(Color.Blue));
listColors.Add(new MyClass(Color.Green));
listColors.Add(new MyClass(Color.Red));
MyClass[] arrayColors = listColors.ToArray();
arrayColors[2].Color1 = Color.Purple;
Console.WriteLine(arrayColors[2].Color1.ToString());
Console.WriteLine(listColors[2].Color1.ToString());
结果:
Color [Purple]
Color [Purple]
如您所见,我使用.ToArray()方法创建了一个数组MyClass,然后更改了此数组的第3个元素,但我不知道为什么List listColors也会更改。
我在带有.NET 2.0的Windows XP上运行此示例。
我尝试在Windows 7上运行此示例,结果如下:
Color [Purple]
Color [Red]
所以我认为,这是.NET框架的问题。
那么在.NET 2.0中是否可以像.NET 4那样进行List的深层复制?这只是一个测试类,在我的工作中,它更大。
非常感谢。
答案 0 :(得分:2)
你没有创建新的MyClass对象试试这个(它给你预期的结果):
List<MyClass> listColors = new List<MyClass>();
listColors.Add(new MyClass(Color.Blue));
listColors.Add(new MyClass(Color.Green));
listColors.Add(new MyClass(Color.Red));
MyClass[] arrayColors = listColors.ToArray();
arrayColors[2] = new MyClass(Color.Purple);
Console.WriteLine(arrayColors[2].Color1.ToString());
Console.WriteLine(listColors[2].Color1.ToString());
在您的代码中,您正在更改包含Red的颜色的MyClass对象的属性,MyClass对象同时包含在列表和数组中。
答案 1 :(得分:0)
ToArray()不执行深层复制,至少不是您期望的意义。它创建一个具有相同对象的数组。我对此主题的最佳解释是:MSDN。
简而言之,当源列表/目标列表/数组都是引用类型时 - 执行浅拷贝,这意味着该数组包含相同的引用。因此,您正在更改原始对象。
答案 2 :(得分:0)
好的,这里有一些与.Net 2.0一起使用的通用方法。拿你需要的那些。
public static IList<T> DeepToList<T>(IEnumerable<T> source) where T : IClonable
{
IList<T> result = new List<T>();
foreach (T t in source)
{
result.Add((T)t.Clone());
}
return result;
}
public static T[] DeepToArray<T>(IEnumerable<T> source) where T : IClonable
{
IList<T> clones = DeepToList(source);
T[] result = new T[clones.Count];
clones.CopyTo(result, 0);
return result;
}
public static T[] DeepToArray<T>(IList<T> source) where T : IClonable
{
T[] result = new T[source.Count];
for (int i = 0; i < source.Count; i++)
{
result[i] = (T)source[i].Clone();
}
return result;
}
要使用它们,MyClass
必须实施IClonable
public class MyClass : IClonable
{
public Color Color1;
public MyClass(Color color)
{
this.Color1 = color;
}
public object Clone()
{
return new MyClass(this.Color1);
}
}
所以你可以做到,
MyColor[] arrayColors = DeepToArray(listColors)