Search code examples
c#linqvaluetuple

Deconstruct Container containing ValueTuple in LINQ


I am able to deconstruct a container via an extension method:

var limits = new[] { MyEnum.A , MyEnum.B , MyEnum.C }
        .ToDictionary( x => x ,
                       x => ( SupportedLimit: GetLimit( x ) , RequiredLimit: 0 ) );

public static class Extensions
{
    public static void Deconstruct<TKey, TVal>(
        this KeyValuePair<TKey , TVal> tuple ,
        out TKey key , out TVal value )
    {
        key = tuple.Key;
        value = tuple.Value;
    }

    public static void Deconstruct<TKey, TVal1, TVal2>(
        this KeyValuePair<TKey , (TVal1,TVal2)> tuple ,
        out TKey key , out TVal1 v1 , out TVal2 v2 )
    {
        key = tuple.Key;
        (v1 , v2) = tuple.Value;
    }
}

// works
foreach( var ( enumVal , supportedLimit , requiredLimit ) in limits )
    Debugger.Break();

How do I deconstruct a container/dictionary containing a System.ValueTuple in LINQ?

// won't work, .Where() expects Func<T,bool> not Func<T1,T2,T3,bool>

var failedLimits = limits.Where( ( _ , sup , req ) => sup < req );

I just wanted to know how (and if) it is possible to deconstruct the ValueTuple in (any) LINQ method. I guess I have to add an extension method for every Linq-method (List-like) + overloads for dictionaries + each amount of values in the ValueTuple. How would it look like for the Where() in the example?


Solution

  • public static class LinqExtensions
    {
        public static IEnumerable<KeyValuePair<TKey,(T1,T2)>> Where<TKey,T1,T2>(
            this IEnumerable<KeyValuePair<TKey,(T1,T2)>> source ,
            Func<TKey,T1,T2, Boolean> predicate )
            => source.Where( predicate );
    }
    
    • Overloads for List-like types + every amount of ValueTuple-parameter