问题描述
小问题:如何修改List
中的单个项目?(或者更准确地说,存储在 List
中的 struct
的成员?)
Short question: How can I modify individual items in a List
? (or more precisely, members of a struct
stored in a List
?)
完整说明:
首先,下面使用的struct
定义:
First, the struct
definitions used below:
public struct itemInfo
{
...(Strings, Chars, boring)...
public String nameStr;
...(you get the idea, nothing fancy)...
public String subNum; //BTW this is the element I'm trying to sort on
}
public struct slotInfo
{
public Char catID;
public String sortName;
public Bitmap mainIcon;
public IList<itemInfo> subItems;
}
public struct catInfo
{
public Char catID;
public String catDesc;
public IList<slotInfo> items;
public int numItems;
}
catInfo[] gAllCats = new catInfo[31];
gAllCats
在加载时填充,并在程序运行时填充.
gAllCats
is populated on load, and so on down the line as the program runs.
当我想对 subItems
数组中的 itemInfo
对象进行排序时,就会出现问题.我正在使用 LINQ 来执行此操作(因为似乎没有任何其他合理的方法可以对非内置类型的列表进行排序).所以这就是我所拥有的:
The issue arises when I want to sort the itemInfo
objects in the subItems
array.I'm using LINQ to do this (because there doesn't seem to be any other reasonable way to sort lists of a non-builtin type).So here's what I have:
foreach (slotInfo sInf in gAllCats[c].items)
{
var sortedSubItems =
from itemInfo iInf in sInf.subItems
orderby iInf.subNum ascending
select iInf;
IList<itemInfo> sortedSubTemp = new List<itemInfo();
foreach (itemInfo iInf in sortedSubItems)
{
sortedSubTemp.Add(iInf);
}
sInf.subItems.Clear();
sInf.subItems = sortedSubTemp; // ERROR: see below
}
错误是无法修改 'sInf' 的成员,因为它是一个 'foreach 迭代变量'".
The error is, "Cannot modify members of 'sInf' because it is a 'foreach iteration variable'".
a,这个限制没有意义;这不是 foreach 结构的主要用途吗?
a, this restriction makes no sense; isn't that a primary use of the foreach construct?
b,(也是出于恶意)如果不修改列表,Clear() 会做什么?(顺便说一句,如果我删除最后一行并运行它,根据调试器,列表确实会被清除.)
b, (also out of spite) what does Clear() do if not modify the list? (BTW, the List does get cleared, according to the debugger, if I remove the last line and run it.)
所以我尝试采用不同的方法,看看它是否可以使用常规的 for 循环.(显然,这只是允许的,因为 gAllCats[c].items
实际上是一个 IList
;我认为它不允许您索引常规的 List
这样.)
So I tried to take a different approach, and see if it worked using a regular for loop. (Apparently, this is only allowable because gAllCats[c].items
is actually an IList
; I don't think it will allow you to index a regular List
this way.)
for (int s = 0; s < gAllCats[c].items.Count; s++)
{
var sortedSubItems =
from itemInfo iInf in gAllCats[c].items[s].subItems
orderby iInf.subNum ascending
select iInf;
IList<itemInfo> sortedSubTemp = new List<itemInfo>();
foreach (itemInfo iInf in sortedSubItems)
{
sortedSubTemp.Add(iInf);
}
//NOTE: the following two lines were incorrect in the original post
gAllCats[c].items[s].subItems.Clear();
gAllCats[c].items[s].subItems = sortedSubTemp; // ERROR: see below
}
这次的错误是无法修改'System.Collections.Generic.IList.this[int]'的返回值,因为它不是变量."啊!如果不是变量,它是什么?什么时候变成返回值"了?
This time, the error is, "Cannot modify the return value of 'System.Collections.Generic.IList.this[int]' because it is not a variable." Ugh! What is it, if not a variable? and when did it become a 'return value'?
我知道必须有一种正确"的方法来做到这一点;我是从 C 背景来的,我知道我可以用 C 来做(尽管需要一些手动内存管理.)
I know there has to be a 'correct' way to do this; I'm coming to this from a C background and I know I could do it in C (albeit with a good bit of manual memory management.)
我四处搜索,似乎 ArrayList
已经过时了,转而支持泛型类型(我使用的是 3.0)并且我不能使用数组,因为大小需要动态.
I searched around, and it seems that ArrayList
has gone out of fashion in favor of generic types (I'm using 3.0) and I can't use an array since the size needs to be dynamic.
推荐答案
查看 for 循环方法,在 编译错误文档:
Looking at the for-loop approach, the reason (and solution) for this is given in the documentation for the compilation error:
试图修改一个值作为结果产生的类型一个中间表达式,但不是存储在一个变量中.这个错误可以当您尝试直接修改泛型中的结构收藏.
要修改struct,先赋值到局部变量,修改变量,然后分配变量返回集合中的项目.
To modify the struct, first assign it to a local variable, modify the variable, then assign the variable back to the item in the collection.
因此,在您的 for 循环中,更改以下几行:
So, in your for-loop, change the following lines:
catSlots[s].subItems.Clear();
catSlots[s].subItems = sortedSubTemp; // ERROR: see below
...进入:
slotInfo tempSlot = gAllCats[0].items[s];
tempSlot.subItems = sortedSubTemp;
gAllCats[0].items[s] = tempSlot;
我删除了对 Clear
方法的调用,因为我认为它没有添加任何内容.
I removed the call to the Clear
method, since I don't think it adds anything.
这篇关于c#修改列表中的结构<T>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!