#if NET20 || NET30 || !NET_4_6 using System.Collections.Generic; namespace System.Linq.Reimplement { public static partial class Enumerable { public static IEnumerable Join(this IEnumerable outer, IEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func resultSelector, IEqualityComparer comparer) { LinqCheck.JoinSelectors(outer, inner, outerKeySelector, innerKeySelector, resultSelector); if (comparer == null) { comparer = EqualityComparer.Default; } return CreateJoinIterator(outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer); } public static IEnumerable Join(this IEnumerable outer, IEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func resultSelector) { return outer.Join(inner, outerKeySelector, innerKeySelector, resultSelector, null); } private static IEnumerable CreateJoinIterator(this IEnumerable outer, IEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func resultSelector, IEqualityComparer comparer) { // NOTICE this method has no null check var innerKeys = ToLookup(inner, innerKeySelector, comparer); foreach (var element in outer) { var outerKey = outerKeySelector(element); if (!ReferenceEquals(outerKey, null) && innerKeys.Contains(outerKey)) { foreach (var innerElement in innerKeys[outerKey]) { yield return resultSelector(element, innerElement); } } } } } } #endif