代码之家  ›  专栏  ›  技术社区  ›  AJ.

更新c中foreach循环中的结构#

  •  7
  • AJ.  · 技术社区  · 15 年前

    我有这个代码(C):

    using System.Collections.Generic;
    
    namespace ConsoleApplication1
    {
        public struct Thing
        {
            public string Name;
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                List<Thing> things = new List<Thing>();
                foreach (Thing t in things) //  for each file
                {
                    t.Name = "xxx";
                }
            }
        }
    }
    

    它无法编译。
    错误是:

    Cannot modify members of 't' because it is a 'foreach iteration variable'
    

    如果我改变 Thing class 而不是 struct 但是,它确实编译。

    有人能解释一下发生了什么事吗?

    4 回复  |  直到 7 年前
        1
  •  9
  •   Henk Holterman    15 年前

    或多或少,编译器不会让您更改foreach中的循环变量(部分)。

    简单使用:

    for(int i = 0; i < things.Count; i+= 1) //  for each file
    {
        things[i].Name = "xxx";
    }
    

    Thing 是一个类,因为循环变量是一个引用,而您只对被引用对象进行更改,而不是对引用本身进行更改。

        2
  •  7
  •   Johannes Rudolph    15 年前

    结构不是引用类型,而是值类型。

    如果你有一个 class 而不是 struct 对于 Thing foreach循环将为您创建一个引用变量,该变量将指向您列表中的正确元素。但由于它是一个值类型,因此它只在 事情 ,在本例中是迭代变量。

        3
  •  2
  •   armannvg    15 年前

    结构是值类型,而类是引用类型。这就是为什么它在这是一个类而不是结构时编译

    查看更多: http://www.albahari.com/valuevsreftypes.aspx

        4
  •  1
  •   Neutrino    7 年前

    我更喜欢@henk的解决方案的另一种语法是。

    DateTime[] dates = new DateTime[10];
    
    foreach(int index in Enumerable.Range(0, dates.Length))
    {
       ref DateTime date = ref dates[index];
    
       // Do stuff with date.
       // ...
    }
    

    如果你在循环中做了大量的工作,那么不必在任何地方重复索引对眼睛来说都比较容易。

    P.S.DateTime实际上是一个非常糟糕的例子,因为它没有任何可以设置的属性,但是您可以得到图片。