【问题标题】:C# strange behaviour in foreach loopC# foreach 循环中的奇怪行为
【发布时间】:2020-07-12 02:28:44
【问题描述】:

经过一天的故障排除后,我设法将问题浓缩为这一小段代码。有人可以向我解释为什么这不起作用吗?当显示消息框时,我希望 [markets] 为 0 2 4 6,[city] [county] 和 [streets] 为 0 1 2 3。

        private void pieceoftestcode()
        {
            string[] county = new string[4];
            string[] city = new string[4];
            string[] markets = new string[4];
            string[] streets = new string[4];
            string[] items = new string[4] { "apple", "banana", "pineapple", "juice" };
            string[] value = new string[4];
            foreach (string item in items)
            {
                for (int i = 0; i <= 3; i++)
                {
                    if (item == "apple")
                        value[i] = (2 * i).ToString();
                    else
                        value[i] = i.ToString();
                }

                if (item == "apple")
                    markets = value;
                else if (item == "banana")
                    streets = value;
                else if (item == "pineapple")
                    county = value;
                else
                    city = value;
            }
            MessageBox.Show("test");
        }

我正在遍历 foreach 循环中的项目。如果项目是“apple”,那么我希望 [value] 为 0 2 4 6。最初 [markets] 分配为 0 2 4 6。但是,如果我逐步执行代码,似乎第二次foreachloop 被执行,[markets] 被覆盖。这是为什么?我在这里做错了什么? [markets] 不应该在香蕉击中后再次赋值吗?

【问题讨论】:

  • 在整个过程中,您只有一个名为 value 的数组,您不断地覆盖并逐渐将来自其他变量的引用分配给同一个数组。
  • "但是,如果我一步一步执行代码,似乎第二次执行 foreachloop 时,[markets] 被覆盖了。" 这是因为markets = value 将两个引用都设置为同一个数组 - 由于您为 values 数组分配了不同的值,因此无论您对数组使用什么引用,您自然可以看到这些更改反映出来。

标签: c# loops foreach


【解决方案1】:

您最终会发现所有各种变量都引用同一个数组 (value),而在设置最后一次迭代时将任何值写入该数组。

有一种非常相似的方法可以避免这个问题:

    private void pieceoftestcode()
    {
        string[] county = new string[4];
        string[] city = new string[4];
        string[] markets = new string[4];
        string[] streets = new string[4];
        string[] items = new string[4] { "apple", "banana", "pineapple", "juice" };
        string[] value;
        foreach (string item in items)
        {
            if (item == "apple")
                value = markets;
            else if (item == "banana")
                value = streets;
            else if (item == "pineapple")
                value = county;
            else
                value = city;
            for (int i = 0; i <= 3; i++)
            {
                if (item == "apple")
                    value[i] = (2 * i).ToString();
                else
                    value[i] = i.ToString();
            }


        }
        MessageBox.Show("test");
    }

现在,每次循环 value 都会被分配一个对不同数组的引用1,因此for 循环不会覆盖它之前的工作.


1假设items 不包含任何重复项,也不包含超过一项非苹果、-香蕉或-菠萝的项。

【讨论】:

  • 我现在明白我们正在创建两个数组之间的链接,而不是将数组中的值从一个数组复制到另一个数组。虽然我确实觉得这有点奇怪,但我知道这可能对记忆有好处。
  • @Maarten - 它不是两个数组之间的链接。您需要弄清变量(例如markets)与该变量当前引用 的数组之间的区别。我们在赋值中所做的只是改变特定变量引用的 which 数组。
【解决方案2】:

你的主要问题是在

            if (item == "apple")
                markets = value;
            else if (item == "banana")
                streets = value;
            else if (item == "pineapple")
                county = value;
            else
                city = value;

声明你不创建一个新数组——你只是将引用分配给对象。然后在 for() 循环中更改数组。

【讨论】:

  • 解决方案是创建数组的深层副本或复制值。主要问题是“我在这里做错了什么”,而不是寻找解决方案
猜你喜欢
  • 1970-01-01
  • 2012-07-11
  • 2014-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多