簡體   English   中英

通過列表和數組中的索引獲取結構項

[英]Get struct item by index in list and array

當我使用struct數組(例如 System.Drawing.Point)時,我可以通過索引獲取項目並更改它。

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

Point[] points = new Point[] { new Point(0,0), new Point(1,1), new Point(2,2) };
for (int i = 0; i < points.Length; i++)
{
    points[i].X += 1;
}

但是當我使用 List 時它不起作用:

無法修改“System.Collections.Generic.List.this[int]”的返回值,因為它不是變量

示例(此代碼不起作用):

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++)
{
    points[i].X += 1;
}

我知道當我按索引獲取列表項時,我得到了它的副本,編譯器提示我沒有犯錯誤,但是為什么采用數組索引的元素工作方式不同?

這是因為陣列points[i]其中對象位於節目。 換句話說,數組的points[i]基本上是內存中的一個指針 因此,您可以在內存中執行記錄操作,而不是在某個副本上執行操作。

這不是List<T> :它在內部使用一個數組,但通過方法進行通信,導致這些方法將從內部數組復制值,顯然修改這些副本沒有多大意義:你立即忘記它們,因為您沒有將副本寫回內部數組。

解決這個問題的方法是,正如編譯器所建議的:

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

因此,您將副本讀入臨時變量,修改副本,然后將其寫回List<T>

原因是結構是值類型,因此當您訪問列表元素時,您實際上將訪問該元素的中間副本,該副本已由列表的索引器返回。

換句話說,當使用List<T> ,您正在創建副本。

MSDN

錯誤信息

無法修改“表達式”的返回值,因為它不是變量

試圖修改作為中間表達式結果的值類型。 因為該值不是持久化的,所以該值將保持不變。

要解決此錯誤,請將表達式的結果存儲在中間值中,或對中間表達式使用引用類型。

解決方案:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM