Get struct item by index in list and array

前端 未结 2 1617
一向
一向 2021-01-02 15:54

When I use an array of structs (for example System.Drawing.Point), I can get item by index and change it.

For example (This code work fine):

<         


        
相关标签:
2条回答
  • 2021-01-02 16:48

    The reason is that structs are value types so when you access a list element you will in fact access an intermediate copy of the element which has been returned by the indexer of the list.

    Other words, when using the List<T>, you're are creating copies.

    MSDN

    Error Message

    Cannot modify the return value of 'expression' because it is not a variable

    An attempt was made to modify a value type that was the result of an intermediate expression. Because the value is not persisted, the value will be unchanged.

    To resolve this error, store the result of the expression in an intermediate value, or use a reference type for the intermediate expression.

    Solution:

    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;
    }
    
    0 讨论(0)
  • 2021-01-02 16:56

    This is because for the array points[i] shows where the object is located. In other words, basically points[i] for an array is a pointer in memory. You thus perform operations on-the-record in memory, not on some copy.

    This is not the case for List<T>: it uses an array internally, but communicates through methods resulting in the fact that these methods will copy the values out of the internal array, and evidently modifying these copies does not make much sense: you immediately forget about them since you do not write the copy back to the internal array.

    A way to solve this problem is, as the compiler suggests:

    (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
    

    So you could use the following "trick":

    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;
    }
    

    So you read the copy into a temporary variable, modify the copy, and write it back to the List<T>.

    0 讨论(0)
提交回复
热议问题