Array.Sort()对原始数组进行排序,而不仅仅是复制

时间:2014-11-29 01:37:41

标签: c# arrays sorting

此代码段来自C#2010 for Dummies。令我困惑的是,当使用Array.Sort()方法时,我的数组副本(sortedNames)和原始数组(行星)都会被排序,即使它只调用sortedNames上的Sort方法。

第二个foreach循环引用哪个数组并不重要,输出是相同的。

static void Main(string[] args)
{
    Console.WriteLine("The 5 planets closest to the sun, in order: ");
    string[] planets = new string[] { "Mercury","Venus", "Earth", "Mars", "Jupiter"};
    foreach (string planet in planets)
    {
        Console.WriteLine("\t" + planet);
    }
    Console.WriteLine("\nNow listed alphabetically: ");


    string[] sortedNames = planets;
    Array.Sort(sortedNames);

    foreach (string planet in planets)
    {
        Console.WriteLine("\t" + planet);
    }
}

2 个答案:

答案 0 :(得分:20)

sortedNamesplanets都指向同一个数组。基本上两个变量都指向内存中的相同位置,因此当您在任一变量上调用Array.Sort时,对这两个变量都会反映对数组的更改。

由于C#中的数组是引用类型,因此sortedNamesplanets"指向"到记忆中的同一个位置。

将此与值类型进行对比,后者将数据保存在自己的内存分配中,而不是指向内存中的其他位置。

如果您希望保持planets完整,可以使用创建全新数组,然后使用Array.Copy使用planets的内容填充新数组:

/* Create a new array that's the same length as the one "planets" points to */
string[] sortedNames = new string[planets.Length];

/* Copy the elements of `planets` into `sortedNames` */
Array.Copy(planets, sortedNames, planets.Length);

/* Sort the new array instead of `planets` */
Array.Sort(sortedNames);

或者,使用LINQ,您可以使用OrderByToArray创建一个新的有序数组:

string[] sortedNames = planets.OrderBy(planet => planet).ToArray();

可能有助于值类型引用类型的一些资源:

答案 1 :(得分:0)

或者,您可以使用 Array.Clone 来避免必须先创建一个新数组。然后排序。

string[] sortedNames = (string[]) Array.Clone(planets);
Array.Sort(sortedNames);

另见其他讨论Difference between the System.Array.CopyTo() and System.Array.Clone()