0

当我尝试使用 .ToArray() 创建一个包含 List 的深层副本的数组时,我遇到了一个问题。

这是我的测试课:

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 的深层复制?这只是一个测试课,在我的工作中,它更大。

非常感谢。

4

3 回答 3

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());

在您的代码中,您正在更改包含红色的 MyClass 对象的属性,MyClass 对象在列表和数组中。

于 2013-10-08T11:08:54.820 回答
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)
于 2013-10-08T11:37:59.757 回答
0

ToArray() 不执行深拷贝,至少不是你期望的那样。它创建一个具有相同对象的数组。我所知道的关于该主题的最佳解释是:MSDN

简而言之,当源和目标列表/数组都是引用类型时 - 执行浅拷贝,这意味着数组包含相同的引用。因此,您正在更改原始对象。

于 2013-10-08T11:11:37.910 回答