复制 IEnumerable,替换一个项目

Copy IEnumerable, replacing an item

我想制作一个 IEnumerable<T> 的副本,其中给定索引处的单个项目已被给定值替换。

我定义了以下方法来执行我想要的操作:

public static IEnumerable<T> ReplaceAt<T>(this IEnumerable<T> source, T item, int index)
{
    foreach (T before in source.Take(index))
    {
        yield return before;
    }

    yield return item;

    foreach (T after in source.Skip(index + 1))
    {
        yield return after;
    }
}

然而,虽然可能很容易理解,但似乎 'inefficient' 创建两个迭代器,其中一个跳过第一个迭代器已经采用的项目。

是否有更好的定义方式?

怎么样:

public static IEnumerable<T> ReplaceAt<T>(this IEnumerable<T> source, T item, int index)
{
    return source.Select((value, i) => index == i ? item : value);
} 

不确定是否有效,但您尝试过吗?

public static IEnumerable<T> ReplaceAt<T>(this IEnumerable<T> source, T item, int index)
{
    return source.Select((x, i) => i == index ? item : x);
}   

如果你想发疯,你可以手动展开foreach

public static IEnumerable<T> ReplaceAt<T>(this IEnumerable<T> source, T item, int index)
{
    int itemIndex = 0;
    using(var iter = source.GetEnumerator())
    {
        while(iter.MoveNext())
        {
            yield return itemIndex++ == index ? item : iter.Current;
        }
    }
}