我有一个条目列表,通过以下命令保存到数据库中 - 缩短 - 代码:
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.
那么我怎么能这样做呢?
答案 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(...));
}
(如果需要,您还可以创建新值列表,而不是修改现有列表。)