【问题标题】:Array.Sort() sorts original array and not just copyArray.Sort() 对原始数组进行排序,而不仅仅是复制
【发布时间】:2014-11-29 01:37:41
【问题描述】:

此代码 sn-p 来自 C# 2010 for Dummies。让我感到困惑的是,当使用 Array.Sort() 方法时,我的数组副本 (sortedNames) 和原始数组 (planets) 都会被排序,即使它只调用 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);
    }
}

【问题讨论】:

  • sortedNamesplanets 指的是同一个对象

标签: c# arrays sorting


【解决方案1】:

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

由于 C# 中的数组是引用类型sortedNamesplanets “指向”内存中的同一位置。

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

如果您想保持planets 不变,可以使用创建一个全新的数组,然后使用Array.Copyplanets 的内容填充新数组:

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

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-20
      • 2021-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-09
      • 1970-01-01
      相关资源
      最近更新 更多