C# 按列表和数组中的索引获取结构项

C# 按列表和数组中的索引获取结构项,c#,arrays,C#,Arrays,当我使用structs数组(例如System.Drawing.Point)时,我可以按索引获取项并对其进行更改 例如(此代码工作正常): Point[]points=新点[]{新点(0,0)、新点(1,1)、新点(2,2)}; 对于(int i=0;i

当我使用
struct
s数组(例如System.Drawing.Point)时,我可以按索引获取项并对其进行更改

例如(此代码工作正常):

Point[]points=新点[]{新点(0,0)、新点(1,1)、新点(2,2)};
对于(int i=0;i
但当我使用列表时,它不起作用:

无法修改的返回值 'System.Collections.Generic.List.this[int]' 因为它不是一个变量

示例(此代码无法正常工作):

List points=newlist{new Point(0,0),new Point(1,1),new Point(2,2)};
对于(int i=0;i

我知道当我按索引获取列表项时,我得到了它的副本和编译器提示我没有犯错误,但是为什么数组索引的元素工作方式不同呢?

原因是结构是值类型,因此当您访问列表元素时,实际上您将访问列表索引器返回的元素的中间副本

换句话说,当使用
列表时,您正在创建副本

错误消息

无法修改“expression”的返回值,因为它不是 变数

试图修改由错误导致的值类型 中间表达。由于该值未持久化,因此 将保持不变

若要解决此错误,请将表达式的结果存储在 中间值,或使用中间值的引用类型 表情

解决方案:

List<Point> points = new List<Point>  { new Point(0,0), new Point(1,1), new Point(2,2) };
for (int i = 0; i < points.Count; i++)
{
    Point p = points[i];
    p.X += 1;
    //and don't forget update the old value, because we're using copy
    points[i] = p;
}
List points=newlist{new Point(0,0),new Point(1,1),new Point(2,2)};
对于(int i=0;i
这是因为对于数组,
点[i]
显示了对象所在的位置。换句话说,数组的
点基本上是内存中的指针。因此,您可以对内存中的记录执行操作,而不是对某些副本执行操作

列表的情况并非如此:它在内部使用数组,但通过方法进行通信,从而导致这些方法将值从内部数组中复制出来,显然,修改这些副本没有多大意义:您会立即忘记它们,因为您不会将副本写回内部数组

正如编译器所建议的,解决此问题的一种方法是:

(3,11): error CS1612: Cannot modify a value type return value of `System.Collections.Generic.List<Point>.this[int]'. Consider storing the value in a temporary variable
(3,11):错误CS1612:无法修改“System.Collections.Generic.List.this[int]”的值类型返回值。考虑将值存储在临时变量中
因此,您可以使用以下“技巧”:

List points=newlist{new Point(0,0),new Point(1,1),new Point(2,2)};
对于(int i=0;i

因此,您将副本读入一个临时变量,修改副本,然后将其写回
列表

,该列表恐怕不会更改列表中的值:请注意
struct
意味着您复制了记录的内容。所以
p
是一个副本,不会对原始列表产生任何影响。@CommuSoft没错,你是对的。但是我已经修好了=)@isxakar:那就拿+1;)
List<Point> points = new List<Point>  { new Point(0,0), new Point(1,1), new Point(2,2) };
for (int i = 0; i < points.Count; i++)
{
    Point p = points[i];
    p.X += 1;
    //and don't forget update the old value, because we're using copy
    points[i] = p;
}
(3,11): error CS1612: Cannot modify a value type return value of `System.Collections.Generic.List<Point>.this[int]'. Consider storing the value in a temporary variable
List<Point> points = new List<Point>  { new Point(0,0), new Point(1,1), new Point(2,2) };
for (int i = 0; i < points.Count; i++) {
    Point p = points[i];
    p.X += 1;
    points[i] = p;
}