写回到列表中

时间:2014-05-22 08:27:30

标签: c# visual-studio list

我有一个条目列表,通过以下命令保存到数据库中 - 缩短 - 代码:

List<MyStruct> myStructList = new JavaScriptSerializer().Deserialize<List<MyStruct>>(postdata);

foreach (MyStruct myStruct in myStructList) {
    if(myStruct.id==0) {
        // Not in DB -> insert.
        myStruct.id = (int)db.ExecuteScalar("INSERT INTO table ...");
    } else {
        ...
    }
}
// return all records with id set to auto-increment value.
return myStructList;

我想返回所有带有更新ID的记录 - 但由于foreach,myStruct.id不可写。所以我用for循环替换了foreach:

for(int i=0;i<myStructList.Count;i++)   //foreach (MyStruct myStruct in myStructList), but writeable
{
    MyStruct myStruct = myStructList[i]
    if(myStruct.id==0) {
        // Not in DB -> insert.
        myStruct.id = (int)db.ExecuteScalar("INSERT INTO table ...");
    }
}
return myStructList;

但更改myStruct不会更改myStructList。

第三次尝试:写回列表。

for(int i=0;i<myStructList.Count;i++)   //foreach (MyStruct myStruct in myStructList), but writeable
{
    MyStruct myStruct = myStructList[i]
    if(myStruct.id==0) {
        // Not in DB -> insert.
        myStructList[i].id = (int)db.ExecuteScalar("INSERT INTO table ...");
    }
}
return myStructList;

返回错误:

Cannot modify the return value of 'System.Collections.Generic.List<MyApp.MyStruct>.this[int]' because it is not a variable.

那么我怎么能这样做呢?

1 个答案:

答案 0 :(得分:6)

问题正是因为你有一个结构 - 以及一个可变的结构。

索引器将返回 - 如果编译器实际上允许您更改该值,则它不会修改列表中已有的值。

选项:

  • 获取值,修改它,然后将其放回列表中:

    MyStruct myStruct = myStructList[i]
    if (myStruct.id==0)
    {
        myStruct.id = (int)db.ExecuteScalar("INSERT INTO table ...");
        // Copy the modified value back into the list
        myStructList[i] = myStruct;
    }
    
  • 将其更改为而不是结构,在这种情况下,您的第一种方法就可以了。

  • 使结构不可变,但创建一个返回 new 值的方法,该值与旧值相同,但具有新ID。那你就用了:

    MyStruct myStruct = myStructList[i]
    if (myStruct.id==0)
    {
        myStructList[i] = myStruct.WithId((int)db.ExecuteScalar(...));
    }
    

(如果需要,您还可以创建值列表,而不是修改现有列表。)

一般来说,mutable structs are a bad idea