You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
56 lines
3.7 KiB
56 lines
3.7 KiB
// Author: Gockner, Simon
|
|
// Created: 2019-07-02
|
|
// Copyright(c) 2019 SimonG. All Rights Reserved.
|
|
|
|
namespace LightweightIocContainer;
|
|
|
|
internal static class EnumerableExtension
|
|
{
|
|
/// <summary>
|
|
/// Returns the first element of a <see cref="IEnumerable{T}"/>, or a new instance of a given <see cref="Type"/> if the <see cref="IEnumerable{T}"/> contains no elements
|
|
/// </summary>
|
|
/// <typeparam name="TSource">The source <see cref="Type"/> of the <see cref="IEnumerable{T}"/></typeparam>
|
|
/// <typeparam name="TGiven">The given <see cref="Type"/> to return if the <see cref="IEnumerable{T}"/> contains no elements</typeparam>
|
|
/// <param name="source">The given <see cref="IEnumerable{T}"/></param>
|
|
/// <returns>The first element of the <see cref="IEnumerable{T}"/>, or a new instance of a given <see cref="Type"/> if the <see cref="IEnumerable{T}"/> contains no elements</returns>
|
|
public static TSource FirstOrGiven<TSource, TGiven>(this IReadOnlyCollection<TSource> source) where TGiven : TSource, new() =>
|
|
source.TryGetFirst<TSource, TGiven>(null);
|
|
|
|
/// <summary>
|
|
/// Returns the first element of a <see cref="IEnumerable{T}"/> that satisfies a condition, or a new instance of a given <see cref="Type"/> if no such element is found
|
|
/// </summary>
|
|
/// <typeparam name="TSource">The source <see cref="Type"/> of the <see cref="IEnumerable{T}"/></typeparam>
|
|
/// <typeparam name="TGiven">The given <see cref="Type"/> to return if the <see cref="IEnumerable{T}"/> contains no element that satisfies the given condition</typeparam>
|
|
/// <param name="source">The given <see cref="IEnumerable{T}"/></param>
|
|
/// <param name="predicate">A function to test each element for a condition</param>
|
|
/// <returns>The first element of the <see cref="IEnumerable{T}"/> that satisfies a condition, or a new instance of the given <see cref="Type"/> if no such element is found</returns>
|
|
public static TSource FirstOrGiven<TSource, TGiven>(this IReadOnlyCollection<TSource> source, Func<TSource, bool> predicate) where TGiven : TSource, new() =>
|
|
source.TryGetFirst<TSource, TGiven>(predicate);
|
|
|
|
/// <summary>
|
|
/// Tries to get the first element of the given <see cref="IEnumerable{T}"/> or creates a new element of a given <see cref="Type"/> when no element is found
|
|
/// </summary>
|
|
/// <typeparam name="TSource">The source <see cref="Type"/> of the <see cref="IEnumerable{T}"/></typeparam>
|
|
/// <typeparam name="TGiven">The given <see cref="Type"/> to create a new element when no fitting element is found</typeparam>
|
|
/// <param name="source">The given <see cref="IEnumerable{T}"/></param>
|
|
/// <param name="predicate">A function to test each element for a condition</param>
|
|
/// <returns>The first element of the <see cref="IEnumerable{T}"/> or a new instance of the given <see cref="Type"/> when no element is found</returns>
|
|
private static TSource TryGetFirst<TSource, TGiven>(this IReadOnlyCollection<TSource> source, Func<TSource, bool>? predicate) where TGiven : TSource, new() =>
|
|
predicate is null ?
|
|
!source.Any() ? new TGiven()
|
|
: source.First()
|
|
: source.Any(predicate) ? source.First(predicate)
|
|
: new TGiven();
|
|
|
|
/// <summary>
|
|
/// Executes an <see cref="Action{T}"/> for each item in an <see cref="IEnumerable{T}"/>
|
|
/// </summary>
|
|
/// <param name="enumerable">The <see cref="IEnumerable{T}"/></param>
|
|
/// <param name="action">The <see cref="Action{T}"/></param>
|
|
/// <typeparam name="T">The <see cref="Type"/> of the items in the <see cref="IEnumerable{T}"/></typeparam>
|
|
public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action)
|
|
{
|
|
foreach (T item in enumerable)
|
|
action(item);
|
|
}
|
|
} |