// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. #pragma warning disable 1591 using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reactive.Concurrency; using System.Reflection; namespace System.Reactive.Linq { /// /// Provides a set of static methods for writing queries over observable sequences, allowing translation to a target query language. /// public static partial class Qbservable { /// /// Returns the input typed as an . /// This operator is used to separate the part of the query that's captured as an expression tree from the part that's executed locally. /// /// The type of the elements in the source sequence. /// An sequence to convert to an sequence. /// The original source object, but typed as an . /// is null. public static IObservable AsObservable(this IQbservable source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } return source; } /// /// Converts an enumerable sequence to an observable sequence. /// /// The type of the elements in the source sequence. /// Enumerable sequence to convert to an observable sequence. /// The observable sequence whose elements are pulled from the given enumerable sequence. /// is null. /// This operator requires the source's object (see ) to implement . public static IQbservable ToQbservable(this IQueryable source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } return ((IQbservableProvider)source.Provider).CreateQuery( Expression.Call( null, #if CRIPPLED_REFLECTION InfoOf(() => ToQbservable(default)), #else ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)), #endif source.Expression ) ); } /// /// Converts an enumerable sequence to an observable sequence, using the specified scheduler to run the enumeration loop. /// /// The type of the elements in the source sequence. /// Enumerable sequence to convert to an observable sequence. /// Scheduler to run the enumeration of the input sequence on. /// The observable sequence whose elements are pulled from the given enumerable sequence. /// or is null. /// This operator requires the source's object (see ) to implement . public static IQbservable ToQbservable(this IQueryable source, IScheduler scheduler) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (scheduler == null) { throw new ArgumentNullException(nameof(scheduler)); } return ((IQbservableProvider)source.Provider).CreateQuery( Expression.Call( null, #if CRIPPLED_REFLECTION InfoOf(() => ToQbservable(default)), #else ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)), #endif source.Expression, Expression.Constant(scheduler) ) ); } internal static Expression GetSourceExpression(IObservable source) { if (source is IQbservable q) { return q.Expression; } return Expression.Constant(source, typeof(IObservable)); } internal static Expression GetSourceExpression(IEnumerable source) { if (source is IQueryable q) { return q.Expression; } return Expression.Constant(source, typeof(IEnumerable)); } internal static Expression GetSourceExpression(IObservable[] sources) { return Expression.NewArrayInit( typeof(IObservable), sources.Select(source => GetSourceExpression(source)) ); } internal static Expression GetSourceExpression(IEnumerable[] sources) { return Expression.NewArrayInit( typeof(IEnumerable), sources.Select(source => GetSourceExpression(source)) ); } internal static MethodInfo InfoOf(Expression> f) { return ((MethodCallExpression)f.Body).Method; } } } #pragma warning restore 1591