C# 生成单个项目并向前移动计数器
我正在处理一个问题,我需要一次向消费者提供一个项目,并将计数器向前移动,以便下一个项目等,直到项目用完。我提出了代码的初稿(见下文)。底层数据结构包含一个字典,其中字符串作为键,另一个字典作为值,该字典保存实体类型的对象 我有一种感觉,我确实需要以某种方式维护状态,所以我尝试使用yield-return语句,但不确定如何将其组合在一起。另外,我认为使用forearch/iterator可能需要调整,因为消费者将调用GetNextItem(),直到它返回false(表示项目用完)C# 生成单个项目并向前移动计数器,c#,dictionary,yield,consumer,producer,C#,Dictionary,Yield,Consumer,Producer,我正在处理一个问题,我需要一次向消费者提供一个项目,并将计数器向前移动,以便下一个项目等,直到项目用完。我提出了代码的初稿(见下文)。底层数据结构包含一个字典,其中字符串作为键,另一个字典作为值,该字典保存实体类型的对象 我有一种感觉,我确实需要以某种方式维护状态,所以我尝试使用yield-return语句,但不确定如何将其组合在一起。另外,我认为使用forearch/iterator可能需要调整,因为消费者将调用GetNextItem(),直到它返回false(表示项目用完) 私有静态字典dt
私有静态字典dt;
私有uint localCounter=0,globalCounter=0;
公共实体GetNextItem()
{
foreach(dt.Keys中的字符串键)
{
如果(MoveCounters(key))//计数器已移动,则处理下一项
{
收益返回dt[键][本地计数器];
}
}
}
专用布尔移动计数器(字符串键)
{
如果(++globalCounter>dt.Count)返回false;//达到极限
如果(++localCounter>dt[key].Count)
{
globalCounter++;
返回true;
}
localCounter++;
返回true;
}
}
公共类实体
{
Dictionary dtValues;//包含CSV文件中的值。
}
移动到下一个子列表时,无法将本地计数器
重置为零
也就是说,您可以更轻松地执行此操作:
foreach (var subdt in dt.Values)
foreach (var item in subdt.Values)
yield return item;
但是使用LINQSelectMany更容易
return dt.Values.SelectMany(subdt => subdt.Values);
请注意,最后一个不使用产生返回值
,因为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;
}
你在哪里给字典加键。。?你不能这样做吗返回dt.Add(dt[key][localCounter])代码>类似的东西..?键将单独添加,就像两次传递系统一样。先把字典填好,然后一旦填好,制作人就可以给你上。谢谢。我想知道,如果产量增加,我可以跟踪哪些项目已处理?对于计数器,通过查看两个计数器的值,我总是知道这一点。我正在考虑维护一个列表,并在其中放入某种值来跟踪它,并在yield return语句之前使用它。@用户:您肯定可以在foreach循环中使用计数器,或者使用keys或KeyValuePair对象。我将添加一个示例。最大的改进是让foreach
为您找到每个子列表的末尾。
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;
}