为什么 AutoMapper 会多次枚举一个 IEnumerable?

Why is AutoMapper enumerating an IEnumerable multiple times?

我们 运行 解决了性能问题并将其追踪到 AutoMapper 在 IEnumerable 上枚举两次。 通过简单地向 AutoMapper 提供一个列表或数组,它很容易在我们这边修复,但我仍然很好奇这是否是预期的行为。

以下最小重现测试失败::

[Test]
public void AutoMapper_Should_Not_Enumerate_Multiple_Times()
{
    var counter = 0;
    var values = Enumerable.Range(0, 3).Select(_ => counter++);
    var mapper = new Mapper(new MapperConfiguration(_ => { }));

    var dest= mapper.Map<int[]>(values);

    Assert.Equal(3, counter);
}

Result: Counter = 6, dest = [3,4,5],表示IEnumerable被迭代了两次,返回了第二次迭代

我尝试在 AutoMapper 中调试它,但我只发现某些东西首先调用 Count() 然后迭代:

这是预期的行为吗? IEnumerable 如何或在何处映射到数组以及为什么在迭代之前调用 Count()?

这是由 ArrayMapper 实现的,实现是功能上 这个:

var count = source.Count();
var array = new TDestination[count];

int i = 0;
foreach (var item in source)
    array[i++] = newItemFunc(item, context);
return array;