我是否可以在.NET中使用某种类似的集合列表来允许我在迭代时附加到它?
var ls = new List<int>();
ls.Add(5);
foreach (var v in ls) {
if (v > 0)
ls.Add(v - 1);
}
//Alternative
var e = ls.GetEnumerator();
while (e.MoveNext()) {
if (e.Current > 0)
ls.Add(e.Current - 1);
}
答案 0 :(得分:6)
为了模仿这样的foreach
循环,我建议使用for
循环,同时迭代向后:
for (int i = ls.Count - 1; i >= 0; --i) {
var v = ls[i];
//TODO: put relevant code from existing foreach loop here
}
或者如果你必须循环前进
int n = ls.Count; // we don't want iterate the items appended
for (int i = 0; i < n; ++i) {
var v = ls[i];
//TODO: put relevant code from existing foreach loop here
}
如果您确实需要使用附加项(请参阅下面的注释),标准for
循环就足够了:
for (int i = 0; i < ls.count; ++i) {
var v = ls[i];
//TODO: put relevant code from existing foreach loop here
}
最后,您可以迭代原始列表的副本:
foreach (var v in ls.ToList()) { // ls.ToList() is a shallow copy of the ls
...
}
答案 1 :(得分:2)
使用for
可以实现此目的。 foreach
在迭代时不允许修改可枚举。
var ls = new List<int>();
ls.Add(5);
for (int i = 0; i < ls.Count; i++) {
var v = ls[i];
if (v > 0)
ls.Add(v - 1);
}
foreach (var v in ls) {
Console.WriteLine(v.ToString());
}
输出:
5
4
3
2
1
0
答案 2 :(得分:1)
我不认为你可以在迭代时直接附加到任何可迭代对象。 但你可以做的是创建一个像这样的临时列表:
var ls = new List<int>();
ls.Add(5);
var tempList = new List<int>();
foreach(var v in ls){
if(v>0)
tempList.Add(v-1);
}
//Update list
foreach(var v in tempList){
ls.Add(v);
}
//Dont forget to clear the tempList if you need it again !
答案 3 :(得分:1)
要在迭代中包含新添加项,请使用索引:
for (int i = 0; i < ls.Count; i++)
{
if (ls[i] > 0) ls.Add(ls[i] - 1);
}
要排除它们(并保留foreach
),请使用List的临时副本:
foreach (int i in ls.ToList())
{
if (i > 0) ls.Add(i - 1);
}
答案 4 :(得分:1)
IMO;这似乎需要一个递归的解决方案;像这样的东西:
public List<int> AddByReduceNo(List<int> list, int no)
{
if (no > 0)
{
list.Add(no - 1);
return AddByReduceNo(list, no - 1);
}
return list;
}
在ls.Add(5)
使用ls = AddByReduceNo(ls, 5);
之后,<
或者只使用ls = AddByReduceNo(ls, 6);
答案 5 :(得分:0)
您可以查看BlockingCollection课程,看看它是否符合您的需求。
此类有一个方法GetConsumingEnumerable,它为您提供IEnumerable
,允许您在该特定时间点迭代集合中的项目。同时,另一个线程可以继续向集合中添加项目。
如果你有一个消费者和一个生产者线程,这个特别有用。