是否有一个Linq方法添加一个单一的项目的IEnumerable <T>?
基本上我正在尝试做这样的事情:
image.Layers
它会为除Parent
层以外的所有图层返回一个IEnumerable,但在某些情况下,我只想做:
image.Layers.With(image.ParentLayer);
因为它只是在几个地方使用,相比之下, image.Layers
满意的通常使用的100年代。 这就是为什么我不想让另一个也返回Parent
层的属性。
一种方法是从项目(例如数组)中创build一个单例序列,然后将其转化为原始数据:
image.Layers.Concat(new[] { image.ParentLayer } )
如果您经常这样做,可以考虑编写一个Append
(或类似的)扩展方法,比如这里列出的扩展方法,这样可以:
image.Layers.Append(image.ParentLayer)
已经有许多实现。 我看起来有点不同(但performance也一样)
另外,我觉得使用相同的名字是可行的(Concat)。 这意味着在处理IEnumerables的IEnumerables时,必须显式提供types说明符,但在我的项目中不会经常发生。
另外,我觉得它也可以控制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; } }
或者,也可以使用隐式创build的数组。 (使用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) { if (null == target) throw new ArgumentException(nameof(target)); return 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) { if (null == target) throw new ArgumentException(nameof(target)); return items.Concat(target); } }
这没有一个单一的方法。 最接近的是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 }); }
您可以使用Enumerable.Concat :
var allLayers = image.Layers.Concat(new[] {image.ParentLayer});
你可以做一些事情:
image.Layers.Concat(new[] { image.ParentLayer });
它将enum和包含你想要添加的东西的单元素数组连接起来
我曾经为此做过一个很好的小function:
public static class CoreUtil { public static IEnumerable<T> AsEnumerable<T>(params T[] items) { return items; } }
现在这是可能的:
image.Layers.Append(CoreUtil.AsEnumerable(image.ParentLayer, image.AnotherLayer))
我使用下面的扩展方法来避免创build一个无用的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; }
有两个序列连接的Concat方法。
如果你喜欢.With的语法,把它写成一个扩展方法。 IEnumerable将不会注意到另一个。
/// <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); }
这个解决scheme是基于realbart的答案 。 我调整它允许使用一个null
值作为参数:
var newCollection = collection.ConcatItems(null)
Append
和Prepend
已经被添加到.NET标准框架中,所以你不再需要编写自己的。 只需做到这一点:
image.Layers.Append(image.ParentLayer)
请参阅.Net Standard 2.0中的43个API,但不包含在.Net Framework 4.6.1中。 为新function的一个很好的列表。