【问题标题】:How to set something in a item in a collection?如何在集合中的项目中设置一些东西?
【发布时间】:2023-03-21 17:04:01
【问题描述】:

我有十个职位,包括 x、y 和姓名。我想将所有 x 设置为 x+1。这该怎么做?我尝试了不同的方法,但我总是知道我无法修改列表。应该使用 for 或 foreach 来完成。

我得到“无法修改“项目”的成员,因为它是 foreach 迭代变量。”

public struct Position
{
    public int x { get; set; }

    public int y{ get; set; }
    public string name{ get; set; }

}
class Program
{
    static void Main(string[] args)
    {

        List<Position> positions = new List<Position>();
        Position position = new Position();
        position.x = 12;
        position.y = 12;
        position.name = "left";
        positions.Add(position);
        position = new Position();
        position.x = 13;
        position.y = 13;
        position.name = "right";
        positions.Add(position);

        Console.WriteLine(positions.Count);

        Console.WriteLine();

        Position newPosition;
        foreach (Position item in positions)
        {   

        }

        Console.WriteLine();
        foreach (Position item in positions)
        {
            Console.WriteLine(item.x + " " + item.name);
        }
    }
}
}

【问题讨论】:

  • item.x++ 在 foreach 中?

标签: c# list


【解决方案1】:

您应该考虑使用类而不是结构。但是,如果这是一个要求。你仍然可以让它工作。问题是你使用了foreach,它实际上总是引用底层列表项,如果项目是引用类型,没问题,但如果是值类型,这个值将是 复制到迭代器。并且对复制迭代器的所有修改都毫无意义。所以需要错误。您肯定必须改用普通的for。然而这还不够。您的positionsList&lt;Position&gt;,当您从中获取一些项目时,由于indexer 的内部实现,实际上返回了一些复制 值。要解决此问题,您可以执行以下操作之一:

第一个解决方案

for(int i = 0; i < positions.Count; i++){
  //copy first
  var current = positions[i];
  //update value
  current.x++;
  //set back to list
  positions[i] = current;
}

第二种解决方案

//convert the list to array so that all the items will be fetched directly 
//without using indexer:
var temp = positions.ToArray();
for(int i = 0; i < temp.Length; i++){
  temp[i].x++;
}

【讨论】:

    【解决方案2】:

    您需要在循环中增加 x。

    如果你想为每个使用一个,那么你还需要将位置设为一个类:

    public class Position
    {
        public int x { get; set; }
    
        public int y{ get; set; }
        public string name{ get; set; }
    
    }
    
    foreach (Position item in positions)
    {   
         item.x = item.x + 1;
    }
    

    【讨论】:

    • 您可能还必须将 Position 设为类而不是结构
    • dbarnes 有道理。如果使用结构而不是类,我将无法工作
    【解决方案3】:

    结构是不可变的类型。因此,一旦分配它,就无法在列表中更改它。 foreach 循环并不是真正的问题。在 foreach 之外编辑列表的元素会产生同样的错误。

    在 Stack Overflow 上有许多问题解决了这个问题,并提供了一些有价值的见解:

    Cannot modify a struct in a list

    Why are mutable structs evil?

    Why are C# structs immutable?

    因此,如果您必须在这种情况下使用结构,则必须创建一个可变结构,即我所读到的 --evil--。

    【讨论】:

      【解决方案4】:

      我希望我能真正理解你的想法:

      int preX1 = 0, PreX2 = 0; 
      for (int i = 0; i <= positions.Count - 1; i++)
      {   
           if(i == 0)
           {
               preX1 = positions[i].x;
           }
           else
           {
               preX2 = positions[i].x;
               positions[i].x = preX1;
               preX1 = preX2;
           }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-05-03
        • 2017-06-26
        • 2013-01-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多