/// <summary> /// Merges differently typed sequences into a <see cref="ValueTuple{T1, T2, T3}"/>. /// </summary> /// <remarks> /// <paramref name="startAtFirstElement"/> determines how the start of the sequence is handled. /// If it's false (the default), the operator only produces elements once all sources have produced their first element. /// If it's true, the sequence starts at the first element produced by any source, /// with default values for any source that has not yet produced a value. /// </remarks> public static IAsyncEnumerable <ValueTuple <T1, T2, T3> > Combine <T1, T2, T3>(this IAsyncEnumerable <T1> source1, IAsyncEnumerable <T2> source2, IAsyncEnumerable <T3> source3, bool startAtFirstElement = false) { if (source1 == null) { throw new ArgumentNullException(nameof(source1)); } if (source2 == null) { throw new ArgumentNullException(nameof(source2)); } if (source3 == null) { throw new ArgumentNullException(nameof(source3)); } return(Defer(() => { var tuple = new CombineTuple <T1, T2, T3>(startAtFirstElement); return new[] { source1.Select(v => tuple.OnNext1(v)), source2.Select(v => tuple.OnNext2(v)), source3.Select(v => tuple.OnNext3(v)), } .Merge() .SkipUntil(t => t.HasValue) .Select(t => t.GetValueOrDefault()); })); }
/// <summary> /// Merges differently typed sequences into a <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/>. /// </summary> /// <remarks> /// <paramref name="startAtFirstElement"/> determines how the start of the sequence is handled. /// If it's false (the default), the operator only produces elements once all sources have produced their first element. /// If it's true, the sequence starts at the first element produced by any source, /// with default values for any source that has not yet produced a value. /// </remarks> public static IAsyncEnumerable <ValueTuple <T1, T2, T3, T4, T5, T6, T7> > Combine <T1, T2, T3, T4, T5, T6, T7>(this IAsyncEnumerable <T1> source1, IAsyncEnumerable <T2> source2, IAsyncEnumerable <T3> source3, IAsyncEnumerable <T4> source4, IAsyncEnumerable <T5> source5, IAsyncEnumerable <T6> source6, IAsyncEnumerable <T7> source7, bool startAtFirstElement = false) { if (source1 == null) { throw new ArgumentNullException(nameof(source1)); } if (source2 == null) { throw new ArgumentNullException(nameof(source2)); } if (source3 == null) { throw new ArgumentNullException(nameof(source3)); } if (source4 == null) { throw new ArgumentNullException(nameof(source4)); } if (source5 == null) { throw new ArgumentNullException(nameof(source5)); } if (source6 == null) { throw new ArgumentNullException(nameof(source6)); } if (source7 == null) { throw new ArgumentNullException(nameof(source7)); } return(Defer(() => { var tuple = new CombineTuple <T1, T2, T3, T4, T5, T6, T7>(startAtFirstElement); return new[] { source1.Select(v => tuple.OnNext1(v)), source2.Select(v => tuple.OnNext2(v)), source3.Select(v => tuple.OnNext3(v)), source4.Select(v => tuple.OnNext4(v)), source5.Select(v => tuple.OnNext5(v)), source6.Select(v => tuple.OnNext6(v)), source7.Select(v => tuple.OnNext7(v)), } .Merge() .SkipUntil(t => t.HasValue) .Select(t => t.GetValueOrDefault()); })); }