Basically I am trying to do something like this:
image.Layers
which returns an IEnumerable for all layers except the Parent
layer,
There is no single method which does this. The closest is the Enumerable.Concat
method but that tries to combine an IEnumerable<T>
with another IEnumerable<T>
. You can use the following to make it work with a single element
image.Layers.Concat(new [] { image.ParentLayer });
Or just add a new extension method
public static IEnumerable<T> ConcatSingle<T>(this IEnumerable<T> enumerable, T value) {
return enumerable.Concat(new [] { value });
}
You can use Enumerable.Concat:
var allLayers = image.Layers.Concat(new[] {image.ParentLayer});
There is the Concat method which joins two sequences.
You can do something like:
image.Layers.Concat(new[] { image.ParentLayer });
which concats the enum with a single-element array containing the thing you want to add
Append
and Prepend
have now been added to the .NET Standard framework, so you no longer need to write your own. Simply do this:
image.Layers.Append(image.ParentLayer)
See What are the 43 APIs that are in .Net Standard 2.0 but not in .Net Framework 4.6.1? for a great list of new functionality.
Many implementations have been given already. Mine looks a bit different (but performs just as well)
Also, I find it practicle to also have control over the ORDER. thus often, I also have a ConcatTo method, putting the new element op front.
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;
}
}
Or alternatively, use an implicitly created array. (using the params keyword) so you can call the method to add one or more items at a time:
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)));