IEnumerable <TResult> JoinCore <TInner, TJoinKey, TResult>(IMemoryFinder <TJoinKey, TInner> innerMemory, Func <TOuter, TJoinKey> keySelector, Func <TOuter, TInner, TResult> resultSelector)
 {
     foreach (var outer in outerList)
     {
         var inner = innerMemory.FindOrDefault(keySelector(outer));
         yield return(resultSelector(outer, inner));
     }
 }
 IEnumerable <TResult> JoinCore <TInner1, TInner2, TJoinKey, TResult>(IMemoryFinder <TJoinKey, TInner1> innerMemory1, IMemoryFinder <TJoinKey, TInner2> innerMemory2, Func <TOuter, TJoinKey> keySelector, Func <TOuter, TInner1, TInner2, TResult> resultSelector)
 {
     foreach (var outer in outerList)
     {
         var key    = keySelector(outer);
         var inner1 = innerMemory1.FindOrDefault(key);
         var inner2 = innerMemory2.FindOrDefault(key);
         yield return(resultSelector(outer, inner1, inner2));
     }
 }