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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions