3

有没有办法用 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());
4

6 回答 6

4

这应该重写。我不知道您使用的是哪种集合,但Current在您的情况下未定义,因为MoveNext可能已经返回false。如文档中所述:

Current 在以下任何情况下都是未定义的: 最后一次调用 MoveNext 返回 false,表示集合结束。

这是我将如何重写它:

bool isEmpty = true;
foreach (Item entry in existingPendingItems)
{
  ProcessEntry(entry, itemToAdd);
  isEmpty = false;
}
if (isEmpty)
{
  ProcessEntry(null, itemToAdd);
}
  • ProcessEntry包含单个条目的逻辑,并且易于单元测试。
  • 该算法被清除读取。
  • 可枚举的仍然只枚举一次。
于 2011-08-03T17:53:33.960 回答
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 提到的错误。

于 2011-08-03T17:49:11.780 回答
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);
}

我认为这使代码的意图更加清晰。

编辑:根据建议将计数更改为任何。还修复了添加数量逻辑

于 2011-08-03T17:48:31.997 回答
0

我会将其重写为更标准的while方法。而且你忘记了IEnumerator<T>implements IDisposable,所以你应该处理它。

于 2011-08-03T17:40:42.727 回答
0
foreach( Item entry in pendingEntries.Current)
{
    if( entry != null)
        entry.Quantity += itemToAdd.Quantity;
    else
       entry = Mapper.Map<ItemDto, Item>(itemToAdd);
    Save(entry)
}

没有这些物品就不能准确地测试它

于 2011-08-03T17:45:26.647 回答
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);
}

这里的想法是在迭代之前为成功做好准备。你要迭代什么?现有条目(如果有),或者只是一个新条目。

通过预先处理这个,你知道你有一些东西可以使用,你的循环保持非常干净。

于 2011-08-03T17:48:32.417 回答