有没有办法用foreach循环更优雅地编写这段代码? “创建新条目”逻辑阻碍了我,因为即使pendingEntries不包含任何项目,它也需要执行。
ItemDto itemToAdd; // an input parameter to the method
IEnumerator<Item> pendingEntries = existingPendingItems.GetEnumerator();
pendingEntries.MoveNext();
do // foreach entry
{
Item entry = pendingEntries.Current;
if (entry != null) // fold the itemToAdd into the existing entry
{
entry.Quantity += itemToAdd.Quantity; // amongst other things
}
else // create a new entry
{
entry = Mapper.Map<ItemDto, Item>(itemToAdd);
}
Save(entry);
} while (pendingEntries.MoveNext());
答案 0 :(得分:4)
这应该重写。我不知道您使用的是哪种类型的集合,但Current
在您的情况下未定义,因为MoveNext
可能已返回false
。如documentation中所述:
在以下任何条件下,当前未定义: 对MoveNext的最后一次调用返回false,表示结束 集合。
以下是我将如何重写它:
bool isEmpty = true;
foreach (Item entry in existingPendingItems)
{
ProcessEntry(entry, itemToAdd);
isEmpty = false;
}
if (isEmpty)
{
ProcessEntry(null, itemToAdd);
}
ProcessEntry
包含单个条目的逻辑,并且可以轻松进行单元测试。答案 1 :(得分:2)
foreach (Item entry in existingPendingItems.DefaultIfEmpty())
{
Item entryToSave;
if (entry != null) // fold the itemToAdd into the existing entry
{
entry.Quantity += itemToAdd.Quantity; // amongst other things
entryToSave = entry;
}
else // create a new entry
{
entryToSave = Mapper.Map<ItemDto, Item>(itemToAdd);
}
Save(entryToSave);
}
密钥是Enumerable.DefaultIfEmpty()调用 - 如果序列为空,这将返回带有default (Item)
项的序列。对于引用类型,这将是null
。
编辑:修复neotapir提到的bug。
答案 2 :(得分:1)
就个人而言,我建议这样的事情:
ItemDto itemToAdd; // an input parameter to the method
if (existingPendingItems.Any())
{
foreach(Item entry in existingPendingItems)
{
entry.Quantity += itemToAdd.Quantity
Save(entry);
}
}
else
{
entry = Mapper.Map<ItemDto, Item>(itemToAdd);
Save(entry);
}
我认为这使得代码的意图更加清晰。
编辑:根据建议将计数更改为任何计数。还修复了添加数量逻辑
答案 3 :(得分:0)
我将其重写为更标准的while
方法。你忘了IEnumerator<T>
实现IDisposable
,所以你应该处理它。
答案 4 :(得分:0)
foreach( Item entry in pendingEntries.Current)
{
if( entry != null)
entry.Quantity += itemToAdd.Quantity;
else
entry = Mapper.Map<ItemDto, Item>(itemToAdd);
Save(entry)
}
无法准确测试它没有项目
答案 5 :(得分:0)
var pendingEntries = existingPendingItems.Any()
? existingPendingItems
: new List<Item> { Mapper.Map<ItemDto, Item>(itemToAdd) };
foreach (var entry in pendingEntries)
{
entry.Quantity += itemToAdd.Quantity; // amongst other things
Save(entry);
}
这里的想法是你在迭代之前为自己做好准备。你要迭代什么?现有条目(如果有),或者只是新条目。
通过预先处理这个问题,所以你知道你有一些可以工作的东西,你的循环保持非常干净。