// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. #if !NO_EXPRESSIONS #pragma warning disable 1591 using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Reactive.Concurrency; 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 IObservable<TSource>. /// 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 IQbservable<TSource> sequence to convert to an IObservable<TSource> sequence. /// The original source object, but typed as an IObservable<TSource>. /// is null. public static IObservable AsObservable(this IQbservable source) { if (source == null) throw new ArgumentNullException("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("source"); return ((IQbservableProvider)source.Provider).CreateQuery( Expression.Call( null, #if CRIPPLED_REFLECTION InfoOf(() => Qbservable.ToQbservable(default(IQueryable))), #else ((MethodInfo)MethodInfo.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("source"); if (scheduler == null) throw new ArgumentNullException("scheduler"); return ((IQbservableProvider)source.Provider).CreateQuery( Expression.Call( null, #if CRIPPLED_REFLECTION InfoOf(() => Qbservable.ToQbservable(default(IQueryable))), #else ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)), #endif source.Expression, Expression.Constant(scheduler) ) ); } internal static Expression GetSourceExpression(IObservable source) { var q = source as IQbservable; if (q != null) return q.Expression; return Expression.Constant(source, typeof(IObservable)); } internal static Expression GetSourceExpression(IEnumerable source) { var q = source as IQueryable; if (q != null) 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 #endif