Skip to content

[API Proposal] Add Join/LeftJoin/RightJoin/GroupJoin overloads and FullJoin #255

Description

@prozolic

Background and motivation

.NET 11 Preview 5 adds tuple-returning overloads for Join, LeftJoin, RightJoin, and GroupJoin without a result selector and FullJoin in standard LINQ.
I would like to propose adding these overloads in ZLinq.

API Proposal

The API follows the pattern established by standard LINQ.

Join/LeftJoin/RightJoin/GroupJoin new overloads

namespace ZLinq
{
    partial class ValueEnumerableExtensions
    {
        // Join
        public static ValueEnumerable<Join<TEnumerator, TEnumerator2, TOuter, TInner, TKey>, (TOuter Outer, TInner Inner)> Join<TEnumerator, TEnumerator2, TOuter, TInner, TKey>(
            this ValueEnumerable<TEnumerator, TOuter> source, 
            ValueEnumerable<TEnumerator2, TInner> inner, 
            Func<TOuter, TKey> outerKeySelector, 
            Func<TInner, TKey> innerKeySelector, 
            IEqualityComparer<TKey>? comparer = null)

        public static ValueEnumerable<Join<TEnumerator, FromEnumerable<TInner>, TOuter, TInner, TKey>, (TOuter Outer, TInner Inner)> Join<TEnumerator, TOuter, TInner, TKey>(
            this ValueEnumerable<TEnumerator, TOuter> source, 
            IEnumerable<TInner> inner, 
            Func<TOuter, TKey> outerKeySelector, 
            Func<TInner, TKey> innerKeySelector, 
            IEqualityComparer<TKey>? comparer = null)

        // LeftJoin
        public static ValueEnumerable<LeftJoin<TEnumerator, TEnumerator2, TOuter, TInner, TKey>, (TOuter Outer, TInner? Inner)> LeftJoin<TEnumerator, TEnumerator2, TOuter, TInner, TKey>(
            this ValueEnumerable<TEnumerator, TOuter> source, 
            ValueEnumerable<TEnumerator2, TInner> inner, 
            Func<TOuter, TKey> outerKeySelector, 
            Func<TInner, TKey> innerKeySelector, 
            IEqualityComparer<TKey>? comparer = null)

        public static ValueEnumerable<LeftJoin<TEnumerator, FromEnumerable<TInner>, TOuter, TInner, TKey>, (TOuter Outer, TInner? Inner)> LeftJoin<TEnumerator, TOuter, TInner, TKey>(
            this ValueEnumerable<TEnumerator, TOuter> source, 
            IEnumerable<TInner> inner, 
            Func<TOuter, TKey> outerKeySelector, 
            Func<TInner, TKey> innerKeySelector, 
            IEqualityComparer<TKey>? comparer = null)

        // RightJoin
        public static ValueEnumerable<RightJoin<TEnumerator, TEnumerator2, TOuter, TInner, TKey>, (TOuter? Outer, TInner Inner)> RightJoin<TEnumerator, TEnumerator2, TOuter, TInner, TKey>(
            this ValueEnumerable<TEnumerator, TOuter> source, 
            ValueEnumerable<TEnumerator2, TInner> inner, 
            Func<TOuter, TKey> outerKeySelector, 
            Func<TInner, TKey> innerKeySelector, 
            IEqualityComparer<TKey>? comparer = null)

        public static ValueEnumerable<RightJoin<TEnumerator, FromEnumerable<TInner>, TOuter, TInner, TKey>, (TOuter? Outer, TInner Inner)> RightJoin<TEnumerator, TOuter, TInner, TKey>(
            this ValueEnumerable<TEnumerator, TOuter> source, 
            IEnumerable<TInner> inner, 
            Func<TOuter, TKey> outerKeySelector, 
            Func<TInner, TKey> innerKeySelector, 
            IEqualityComparer<TKey>? comparer = null)

        // GroupJoin
        public static ValueEnumerable<GroupJoin<TEnumerator, TEnumerator2, TOuter, TInner, TKey>, IGrouping<TOuter, TInner>> GroupJoin<TEnumerator, TEnumerator2, TOuter, TInner, TKey>(
            this ValueEnumerable<TEnumerator, TOuter> source, 
            ValueEnumerable<TEnumerator2, TInner> inner, 
            Func<TOuter, TKey> outerKeySelector, 
            Func<TInner, TKey> innerKeySelector, 
            IEqualityComparer<TKey>? comparer = null)

        public static ValueEnumerable<GroupJoin<TEnumerator, FromEnumerable<TInner>, TOuter, TInner, TKey>, IGrouping<TOuter, TInner>> GroupJoin<TEnumerator, TOuter, TInner, TKey>(
            this ValueEnumerable<TEnumerator, TOuter> source, 
            IEnumerable<TInner> inner, 
            Func<TOuter, TKey> outerKeySelector, 
            Func<TInner, TKey> innerKeySelector, 
            IEqualityComparer<TKey>? comparer = null)
}

FullJoin

namespace ZLinq
{
    partial class ValueEnumerableExtensions
    {
        // FullJoin
        public static ValueEnumerable<FullJoin<TEnumerator, TEnumerator2, TOuter, TInner, TKey, TResult>, TResult> FullJoin<TEnumerator, TEnumerator2, TOuter, TInner, TKey, TResult>(
            this ValueEnumerable<TEnumerator, TOuter> source, 
            ValueEnumerable<TEnumerator2, TInner> inner, 
            Func<TOuter, TKey> outerKeySelector, 
            Func<TInner, TKey> innerKeySelector, 
            Func<TOuter?, TInner?, TResult> resultSelector, 
            IEqualityComparer<TKey>? comparer = null)

        public static ValueEnumerable<FullJoin<TEnumerator, TEnumerator2, TOuter, TInner, TKey, (TOuter?, TInner?)>, (TOuter?, TInner?)> FullJoin<TEnumerator, TEnumerator2, TOuter, TInner, TKey>(
            this ValueEnumerable<TEnumerator, TOuter> source, 
            ValueEnumerable<TEnumerator2, TInner> inner, 
            Func<TOuter, TKey> outerKeySelector, 
            Func<TInner, TKey> innerKeySelector, 
            IEqualityComparer<TKey>? comparer = null)

        public static ValueEnumerable<FullJoin<TEnumerator, FromEnumerable<TInner>, TOuter, TInner, TKey, TResult>, TResult> FullJoin<TEnumerator, TOuter, TInner, TKey, TResult>(
            this ValueEnumerable<TEnumerator, TOuter> source, 
            IEnumerable<TInner> inner, 
            Func<TOuter, TKey> outerKeySelector, 
            Func<TInner, TKey> innerKeySelector, 
            Func<TOuter?, TInner?, TResult> resultSelector, 
            IEqualityComparer<TKey>? comparer = null)

        public static ValueEnumerable<FullJoin<TEnumerator, FromEnumerable<TInner>, TOuter, TInner, TKey, (TOuter?, TInner?)>, (TOuter?, TInner?)> FullJoin<TEnumerator, TOuter, TInner, TKey>(
            this ValueEnumerable<TEnumerator, TOuter> source, 
            IEnumerable<TInner> inner, 
            Func<TOuter, TKey> outerKeySelector, 
            Func<TInner, TKey> innerKeySelector, 
            IEqualityComparer<TKey>? comparer = null)
}

Related (dotnet/runtime API Proposal)

dotnet/runtime#120596
dotnet/runtime#120587
dotnet/runtime#124787

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions