是否有Linq方法将单个项添加到IEnumerable <t>?</t>

时间:2011-02-03 19:08:00

标签: c# .net ienumerable

基本上我正在尝试做这样的事情:

image.Layers

为除Parent图层以外的所有图层返回IEnumerable,但在某些情况下,我只想这样做:

image.Layers.With(image.ParentLayer);

因为它仅在少数几个地方使用,而image.Layers满足通常使用的100。这就是为什么我不想创建另一个也返回Parent图层的属性。

11 个答案:

答案 0 :(得分:46)

一种方法是从项目(例如数组)中创建单个序列,然后将Concat创建到原始序列上:

image.Layers.Concat(new[] { image.ParentLayer } )

如果您经常这样做,请考虑编写一个Append(或类似的)扩展方法,例如listed here,这样可以让您这样做:

image.Layers.Append(image.ParentLayer)

答案 1 :(得分:26)

已经提供了许多实现。 我看起来有点不同(但也表现得很好)

另外,我发现也可以控制ORDER。因此,我经常使用ConcatTo方法,将新元素放在前面。

public static class Utility
{
    /// <summary>
    /// Adds the specified element at the end of the IEnummerable.
    /// </summary>
    /// <typeparam name="T">The type of elements the IEnumerable contans.</typeparam>
    /// <param name="target">The target.</param>
    /// <param name="item">The item to be concatenated.</param>
    /// <returns>An IEnumerable, enumerating first the items in the existing enumerable</returns>
    public static IEnumerable<T> ConcatItem<T>(this IEnumerable<T> target, T item)
    {
        if (null == target) throw new ArgumentException(nameof(target));
        foreach (T t in target) yield return t;
        yield return item;
    }

    /// <summary>
    /// Inserts the specified element at the start of the IEnumerable.
    /// </summary>
    /// <typeparam name="T">The type of elements the IEnumerable contans.</typeparam>
    /// <param name="target">The IEnummerable.</param>
    /// <param name="item">The item to be concatenated.</param>
    /// <returns>An IEnumerable, enumerating first the target elements, and then the new element.</returns>
    public static IEnumerable<T> ConcatTo<T>(this IEnumerable<T> target, T item)
    {
        if (null == target) throw new ArgumentException(nameof(target));
        yield return item;
        foreach (T t in target) yield return t;
    }
}

或者,使用隐式创建的数组。 (使用 params 关键字),这样您就可以调用该方法一次添加一个或多个项目:

public static class Utility
{
    /// <summary>
    /// Adds the specified element at the end of the IEnummerable.
    /// </summary>
    /// <typeparam name="T">The type of elements the IEnumerable contans.</typeparam>
    /// <param name="target">The target.</param>
    /// <param name="items">The items to be concatenated.</param>
    /// <returns>An IEnumerable, enumerating first the items in the existing enumerable</returns>
    public static IEnumerable<T> ConcatItems<T>(this IEnumerable<T> target, params T[] items) =>
        (target ?? throw new ArgumentException(nameof(target))).Concat(items);

    /// <summary>
    /// Inserts the specified element at the start of the IEnumerable.
    /// </summary>
    /// <typeparam name="T">The type of elements the IEnumerable contans.</typeparam>
    /// <param name="target">The IEnummerable.</param>
    /// <param name="items">The items to be concatenated.</param>
    /// <returns>An IEnumerable, enumerating first the target elements, and then the new elements.</returns>
    public static IEnumerable<T> ConcatTo<T>(this IEnumerable<T> target, params T[] items) =>
        items.Concat(target ?? throw new ArgumentException(nameof(target)));

答案 2 :(得分:12)

没有一种方法可以做到这一点。最接近的是Enumerable.Concat方法,但会尝试将IEnumerable<T>与另一个IEnumerable<T>合并。您可以使用以下内容使其适用于单个元素

image.Layers.Concat(new [] { image.ParentLayer });

或者只是添加新的扩展方法

public static IEnumerable<T> ConcatSingle<T>(this IEnumerable<T> enumerable, T value) {
  return enumerable.Concat(new [] { value });
}

答案 3 :(得分:7)

您可以使用Enumerable.Concat

var allLayers = image.Layers.Concat(new[] {image.ParentLayer});

答案 4 :(得分:6)

AppendPrepend现已添加到.NET标准框架中,因此您不再需要编写自己的。只需这样做:

image.Layers.Append(image.ParentLayer)

请参阅What are the 43 APIs that are in .Net Standard 2.0 but not in .Net Framework 4.6.1?以获取一系列新功能。

答案 5 :(得分:5)

您可以执行以下操作:

image.Layers.Concat(new[] { image.ParentLayer });

使用包含要添加的内容的单元素数组来连接枚举

答案 6 :(得分:5)

我曾经为此做过一个很好的小功能:

public static class CoreUtil
{    
    public static IEnumerable<T> AsEnumerable<T>(params T[] items)
    {
        return items;
    }
}

现在这是可能的:

image.Layers.Append(CoreUtil.AsEnumerable(image.ParentLayer, image.AnotherLayer))

答案 7 :(得分:3)

如果您喜欢.With的语法,请将其写为扩展方法。 IEnumerable不会注意到另一个。

答案 8 :(得分:3)

我使用以下扩展方法来避免创建无用的Array

public static IEnumerable<T> ConcatSingle<T>(this IEnumerable<T> enumerable, T value) {
   return enumerable.Concat(value.Yield());
}

public static IEnumerable<T> Yield<T>(this T item) {
    yield return item;
}

答案 9 :(得分:1)

Concat方法连接两个序列。

答案 10 :(得分:0)

/// <summary>Concatenates elements to a sequence.</summary>
/// <typeparam name="T">The type of the elements of the input sequences.</typeparam>
/// <param name="target">The sequence to concatenate.</param>
/// <param name="items">The items to concatenate to the sequence.</param>
public static IEnumerable<T> ConcatItems<T>(this IEnumerable<T> target, params T[] items)
{
    if (items == null)
        items = new [] { default(T) };
    return target.Concat(items);
}

此解决方案基于realbart's answer。我调整它以允许使用单个null值作为参数:

var newCollection = collection.ConcatItems(null)