【问题标题】:c# why do I get the same output using classes?c#为什么我使用类得到相同的输出?
【发布时间】:2022-01-15 05:19:48
【问题描述】:

我编写了对给定输入进行排序的代码,但在返回排序后的输入后,它总是会返回相同的输出。我正在 Visual Studio 中使用 .NET 5.0(当前)创建控制台应用程序。

当我输入“Car Apple Banana”作为输入时,它会以 words.Sorted() 进行排序

之后我打印出原始输入,但它似乎也被排序了。我不知道为什么,因为我从不排序。

当输入为:“Car Apple Banana”时

我现在得到的输出是:

苹果香蕉车

苹果香蕉车

虽然需要:

苹果香蕉车

汽车苹果香蕉

主要代码如下:

using System;
using System.Threading.Tasks;
using System.Linq;
using System.Collections.Generic;

namespace _10_Words
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] input_1 = Console.ReadLine().Split(' ');
            Words words = new Words(input_1);

            Console.WriteLine(words.Sorted());
            Console.WriteLine(words.Normal());
        }
    }
}

这是课程代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _10_Words
{
    class Words
    {
        public string[] Output { get; set; }

        public Words(string[] input)
        {
            Output = input;
        }

        public string Sorted()
        {
            string[] sorted = Output;

            Array.Sort(sorted);

            string sorted_array = string.Join(" ", sorted);
            return Convert.ToString(sorted_array);
        }

        public string Normal()
        {
            string[] normal = Output;

            string normal_output = string.Join(" ", normal);
            return Convert.ToString(normal_output);
        }
    }
}

【问题讨论】:

  • 先尝试拨打Normal()。您的 Sorted() 电话正在更改数组。
  • string[] sorted = Output 没有复制 array,它只是将 reference 复制到数组中到一个新变量中。所以,是的,当您排序时,您正在对实际存在的一个数组进行排序。
  • @LarsTech ,我将向它添加更多不同的类,这样就无济于事了
  • @Damien_The_Unbeliever 如何让它复制实际的数组?
  • 你必须使用 Array.Copy。检查 .NET 文档。

标签: c# oop


【解决方案1】:
string[] sorted = Output;

Array.Sort(sorted);

当您调用Array.Sort 时,这修改您传递给它的数组。因为数组是通过引用传递的,sortedOutput 引用同一个数组,它会被排序。

换句话说,当您对元素进行排序时,您正在更改Output

最简单的解决方法是确保创建一个数组,其中的元素与旧数组相同:

// Don't forget to include this at the top of the file
using System.Linq;

string[] sorted = Output.ToArray();

Array.Sort(sorted);

另一种解决方案是将排序更改为不改变输入数组并返回一个新的(排序的)数组的方法:

// Don't forget to include this at the top of the file
using System.Linq;

string[] sorted = Output.OrderBy(x => x).ToArray();

这两种解决方案都使用 LINQ,这使得数组(和列表)操作更易于阅读(恕我直言)。

【讨论】:

  • 哦,好吧,如果我在进行 sorted = output 时做对了,它实际上是指输出的实际值并对其进行更改。所以我需要制作输出的副本,以便可以重复使用。 @O。 R. Mapper 发布了另一个答案,它是引用类型的链接,我一定会检查出来。这将有助于我未来的进步。谢谢!
【解决方案2】:

您似乎认为该行

string[] sorted = Output;

input 复制到Output,然后您可以对Output 进行排序,同时保持input 不变。

事实并非如此。

数组是reference types。因此,当您将类似Output 的数组分配给另一个数组变量(例如sortedsortedOutput)时,将引用同一个数组

如果你想要一个副本,你将不得不遍历元素或使用辅助方法,例如Array.Copy

sorted = new string[Output.Length];
Array.Copy(Output, sorted, Output.Length);

【讨论】:

    【解决方案3】:

    当你写作时

    string[] sorted = Output;
    

    您正在分配对数组输出的引用以进行排序,然后您就地排序

    Array.Sort(sorted);
    

    但由于 sorted 只是对 Output 的引用,因此您实际上是在对 Output 进行排序。更好的方法是直接打印原始数组,然后对其进行排序,然后打印。

    【讨论】:

    • 我注意到,虽然我在搞乱代码,但这不会有帮助,因为我会为单词类添加更多引用,这也会改变输出。
    猜你喜欢
    • 1970-01-01
    • 2021-01-08
    • 2020-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-26
    • 2021-03-23
    相关资源
    最近更新 更多