我正在解决一个问题,我需要一次向消费者提供一个项目,并向前移动计数器,以便下一个项目,依此类推,直到用完为止。我想出了初步的代码草案(见下文)。底层数据结构包含一个Dictionary,它包含字符串作为其键,并保存另一个字典作为其值,其中包含Entity类型的对象。
我有一种感觉,我确实需要以某种方式维持状态,所以我尝试使用yield return语句但不确定如何将它一起混淆。另外我认为使用forearch / iterator可能需要调整,因为使用者会调用GetNextItem()直到它返回false(意味着用完项目)。
private static Dictionary<string, Dictionary <uint,Entity>> dt;
private uint localCounter=0 , globalCounter = 0;
public Entity GetNextItem()
{
foreach (string key in dt.Keys )
{
if (MoveCounters(key)) //counter is moved, so process the next item
{
yield return dt[key][localCounter];
}
}
}
private bool MoveCounters(string key)
{
if (++globalCounter > dt.Count) return false; //hit the limit
if (++localCounter > dt[key].Count)
{
globalCounter++;
return true;
}
localCounter++;
return true;
}
}
public class Entity
{
Dictionary<string, string> dtValues; //contains values from CSV file.
}
答案 0 :(得分:0)
当您转到下一个子列表时,您未能将localCounter
重置为零。
那就是说,你可以这么容易做到:
foreach (var subdt in dt.Values)
foreach (var item in subdt.Values)
yield return item;
但使用LINQ SelectMany
return dt.Values.SelectMany(subdt => subdt.Values);
请注意,最后一个不使用yield return
,因为LINQ产生了可枚举,你只需返回它。
如果您还要记录键和计数器,请尝试以下操作:
int iList = 0;
foreach( var subdt in dt ) {
/* log iList, subdt.Key */
int iItem = 0;
foreach( var item in subdt.Value ) {
/* log iItem, item.Key */
++iItem;
yield return item.Value;
}
++iList;
}