不可变插入选项

时间:2018-09-23 18:36:06

标签: c# collections insert

我正在寻找标准Collection<T>.Insert(Int32, T)方法的不变选择。

在我的特定情况下,我有这样的方法:

IEnumerable<int> Foo(IEnumerable<int> parameter, int index)
{
    var copiedParameter = new List<int>(parameter);
    copiedParameter.Insert(index, 42);
    return copiedParameter;
}

这显然是相当疲惫和低效的。我需要这样的东西:

IEnumerable<int> Foo(IEnumerable<int> parameter, int index) => parameter.InsertImmutable(index, 42);

我当然可以编写这样的扩展方法:

public static IEnumerable<T> InsertImmutable<T>(this IEnumerable<T> collection, int index, T value)
{
    var copiedCollection = new List<T>(collection);
    copiedCollection.Insert(index, value);
    return copiedCollection;
}

但这显然并不能真正改善情况,只是将问题转移到另一个地方。

我能想到的唯一的其他方法是这样的:

public static IEnumerable<T> InsertImmutable<T>(this IEnumerable<T> collection, int index, T value)
{
    var i = 0;
    foreach (var item in collection)
    {
        if (i == index)
            yield return value;
        yield return item;

        i++;
    }
}

但是,这会迭代IEnumerable,这会再次降低效率。

是否有更好,懒惰和不变的方法来做到这一点?

1 个答案:

答案 0 :(得分:0)

实际上,正如评论已向我暗示的那样,解决方案已几乎成为问题。以下代码很好地解决了我的问题:

private static IEnumerable<T> InsertImmutable<T>(this IEnumerable<T> collection, int index, T value)
{
    var i = 0;
    var inserted = false;
    foreach (var item in collection)
    {
        if (i == index)
        {
            inserted = true;
            yield return value;
        }

        yield return item;

        i++;
    }

    if (!inserted)
        yield return value;
}