【问题标题】:C# Set property of object while iterating on it in listC#在列表中迭代对象时设置对象的属性
【发布时间】:2017-12-02 06:10:33
【问题描述】:

C# 不允许我这样做。

foreach (Point point in filledPoints)
{
    point.X = 0;
} 

filledPoints 是一个List<Point> 它给了我一个编译器错误:“filledPoints 是一个 foreach 迭代变量,因此无法编辑关联的成员”(对不起,该消息是德语,我不擅长翻译)。但这有效:

foreach (Point point in filledPoints)
{
    Point point2 = point;
    point2.X = point2.X / oldSize.Width * Size.Width;
}   

为什么这不起作用,有没有更优雅的方法可以绕过它?

【问题讨论】:

  • 错误信息告诉你它为什么不起作用。
  • 它只是告诉我它不起作用但不是为什么@Servy
  • 我怀疑它是否会告诉您That it doesn't work 还会在哪一行引发错误......?你知道如何使用调试器..?如果是这样设置断点并告诉我们有效的错误
  • @KeineAhnung 您使用的是哪个版本的 Visual Studio/.NET/C#?我找不到将" it doesn't work" 作为错误消息的版本。
  • @KeineAhnung 忽略我,我在开玩笑。尝试并简化:您收到该错误的原因是因为您正在修改 foreach 中的值(不允许这样做)。通常使用引用类型可以修改属性,但Point 不是引用类型,它是struct。因此,当您尝试修改属性时,实际上是在修改整个事物。

标签: c# properties iteration


【解决方案1】:

这是因为 Point 不是引用类型(它是结构而不是类)。所以foreach中的point变量实际上并不是对原始Point的引用,它是一个副本。编译器不允许您修改它,因为(我假设)很容易认为您正在更改原始版本。

我不确定是否有更好的方法,但您可以通过执行以下操作来解决此问题:

for (int i = 0; i < filledPoints.Count; i++)
{
    Point temp = filledPoints[i];
    temp.X = 10;
    filledPoints[i] = temp;
}

【讨论】:

  • 这是有道理的。是否有替代课程或者我需要创建它?
  • 这有点乱,但您可以使用 for 循环和临时 Point 变量。我会用一个例子来编辑我的答案。
  • @Joeyrp 不要删除代码,这是正确的做法。我讨厌让未来的读者重新创建 OP 所采用的糟糕的解决方案。至于OP,你应该真正听取人们的建议而不是忽视它。
【解决方案2】:

@Cathal 很接近。您需要使用这样的 for 循环:

for(int i = 0; i < points.Length; i++)
{
    //This copies the value of the point at the i index into a variable called point
    Point point = points[i];

    //Modifying the point.X property of the copy
    point.X = 0;

    //This replaces the point that is at the i index, with the new point that has the modified X property
    points[i] = point;
} 

小提琴here

编辑

我在我的小提琴中添加了一些 cmets 和其他代码来说明为什么你的 foreach 没有按照你的方式工作。认为

【讨论】:

  • 那是我已经不使用 foreach 循环的东西。谢谢,但不需要更多帮助:D
  • @KeineAhnung 我认为您的foreach 循环也不会按照您想要的方式工作。您可能想重新查看我的答案。
  • A struct 是一种值类型,因此当您创建一个新变量时,它会复制现有的 struct 值。然后您修改 并将其重新添加到列表中。这正是您需要做的。您应该Point 进行一对一的课程,因为您不了解struct。我试图向你解释,但你很固执。 看小提琴
  • @KeineAhnung 您也以正确的方式接受了答案。只是不要创建自己的课程。 使用结构
  • @macceturra 我现在明白了。对不起!
【解决方案3】:

如果您使用 for 循环,您将能够分配给存储在filledPoints 中的对象。

for (int i = 0; i < filledPoints.Length; i++)
{
    filledPoints[i].X = 0;  // replace 0 with the desired value
}

注意:根据您使用的集合类型,您可能需要将上述代码中的“.Length”替换为“.Count()”。

【讨论】:

  • 不,不起作用。您忘记了填充点 [i] 末尾的 .X。另外,如果我添加它也不起作用
  • "来自\"List.this[int]\"的返回值是无变量的"
  • 更新添加“.X”道歉
  • 还是不行。感谢您提供帮助,但我知道原因。这是因为 Point 是一个结构,而不是一个类。
  • 如果您使用数组而不是通用集合,您将能够修改值,请参阅:stackoverflow.com/questions/14945118/… 更多澄清可能会有所帮助:)
猜你喜欢
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 2016-02-26
  • 2015-08-29
  • 2019-02-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多