| File: System\Linq\Utilities.cs | Web Access |
| Project: src\runtime\src\libraries\System.Linq\src\System.Linq.csproj (System.Linq) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; namespace System.Linq { /// <summary> /// Contains helper methods for System.Linq. /// </summary> internal static class Utilities { /// <summary> /// Decides if two equality comparers are equivalent. /// </summary> /// <typeparam name="TSource">The type of each comparer.</typeparam> /// <param name="left">The first comparer.</param> /// <param name="right">The second comparer.</param> /// <returns><c>true</c> if the equality comparers are equal; otherwise, <c>false</c>.</returns> public static bool AreEqualityComparersEqual<TSource>(IEqualityComparer<TSource>? left, IEqualityComparer<TSource>? right) { if (left == right) { return true; } var defaultComparer = EqualityComparer<TSource>.Default; if (left is null) { // Micro-opt: Typically it's impossible to get a different instance // of the default comparer without reflection/serialization. // Save a virtual method call to Equals in the common case. return right == defaultComparer || right!.Equals(defaultComparer); } if (right is null) { return left == defaultComparer || left.Equals(defaultComparer); } return left.Equals(right); } /// <summary> /// Combines two predicates. /// </summary> /// <typeparam name="TSource">The type of the predicate argument.</typeparam> /// <param name="predicate1">The first predicate to run.</param> /// <param name="predicate2">The second predicate to run.</param> /// <returns> /// A new predicate that will evaluate to <c>true</c> only if both the first and /// second predicates return true. If the first predicate returns <c>false</c>, /// the second predicate will not be run. /// </returns> public static Func<TSource, bool> CombinePredicates<TSource>(Func<TSource, bool> predicate1, Func<TSource, bool> predicate2) => x => predicate1(x) && predicate2(x); /// <summary> /// Combines two selectors. /// </summary> /// <typeparam name="TSource">The type of the first selector's argument.</typeparam> /// <typeparam name="TMiddle">The type of the second selector's argument.</typeparam> /// <typeparam name="TResult">The type of the second selector's return value.</typeparam> /// <param name="selector1">The first selector to run.</param> /// <param name="selector2">The second selector to run.</param> /// <returns> /// A new selector that represents the composition of the first selector with the second selector. /// </returns> public static Func<TSource, TResult> CombineSelectors<TSource, TMiddle, TResult>(Func<TSource, TMiddle> selector1, Func<TMiddle, TResult> selector2) => x => selector2(selector1(x)); } }