// 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