| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 | // 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. using System.Collections.Generic;using System.Linq.Expressions;using System.Threading;using System.Threading.Tasks;namespace System.Linq{    /// <summary>    /// Representation of an asynchronous enumerable sequence using an expression tree.    /// </summary>    internal abstract class AsyncEnumerableQuery    {        /// <summary>        /// Gets the enumerable sequence obtained from evaluating the expression tree.        /// </summary>        internal abstract object Enumerable { get; }        /// <summary>        /// Gets the expression tree representing the asynchronous enumerable sequence.        /// </summary>        internal abstract Expression Expression { get; }    }    /// <summary>    /// Representation of an asynchronous enumerable sequence using an expression tree.    /// </summary>    /// <typeparam name="T">The type of the elements in the sequence.</typeparam>    internal class AsyncEnumerableQuery<T> : AsyncEnumerableQuery, IOrderedAsyncQueryable<T>, IAsyncQueryProvider    {        private readonly Expression _expression;        private IAsyncEnumerable<T> _enumerable;        /// <summary>        /// Creates a new asynchronous enumerable sequence represented by the specified expression tree.        /// </summary>        /// <param name="expression">The expression tree representing the asynchronous enumerable sequence.</param>        public AsyncEnumerableQuery(Expression expression)        {            _expression = expression;        }        /// <summary>        /// Creates a new asynchronous enumerable sequence by wrapping the specified sequence in an expression tree representation.        /// </summary>        /// <param name="enumerable">The asynchronous enumerable sequence to represent using an expression tree.</param>        public AsyncEnumerableQuery(IAsyncEnumerable<T> enumerable)        {            _enumerable = enumerable;            _expression = Expression.Constant(this);        }        /// <summary>        /// Gets the type of the elements in the sequence.        /// </summary>        Type IAsyncQueryable.ElementType        {            get            {                return typeof(T);            }        }        /// <summary>        /// Gets the expression representing the sequence.        /// </summary>        Expression IAsyncQueryable.Expression        {            get            {                return _expression;            }        }        /// <summary>        /// Gets the query provider used to execute the sequence.        /// </summary>        IAsyncQueryProvider IAsyncQueryable.Provider        {            get            {                return this;            }        }        /// <summary>        /// Gets the enumerable sequence obtained from evaluating the expression tree.        /// </summary>        internal override object Enumerable        {            get            {                return _enumerable;            }        }        /// <summary>        /// Gets the expression tree representing the asynchronous enumerable sequence.        /// </summary>        internal override Expression Expression        {            get            {                return _expression;            }        }        /// <summary>        /// Creates a new asynchronous enumerable sequence represented by an expression tree.        /// </summary>        /// <typeparam name="TElement">The type of the elements in the sequence.</typeparam>        /// <param name="expression">The expression tree representing the asynchronous enumerable sequence.</param>        /// <returns>Asynchronous enumerable sequence represented by the specified expression tree.</returns>        IAsyncQueryable<TElement> IAsyncQueryProvider.CreateQuery<TElement>(Expression expression)        {            return new AsyncEnumerableQuery<TElement>(expression);        }        /// <summary>        /// Executes an expression tree representing a computation over asynchronous enumerable sequences.        /// </summary>        /// <typeparam name="TResult">The type of the result of evaluating the expression tree.</typeparam>        /// <param name="expression">The expression tree to evaluate.</param>        /// <param name="token">Cancellation token used to cancel the evaluation.</param>        /// <returns>Task representing the result of evaluating the specified expression tree.</returns>        Task<TResult> IAsyncQueryProvider.ExecuteAsync<TResult>(Expression expression, CancellationToken token)        {            if (expression == null)            {                throw new ArgumentNullException(nameof(expression));            }            if (!typeof(Task<TResult>).IsAssignableFrom(expression.Type))            {                throw new ArgumentException("The specified expression is not assignable to the result type.", nameof(expression));            }            return new AsyncEnumerableExecutor<TResult>(expression).ExecuteAsync(token);        }        /// <summary>        /// Gets an enumerator to enumerate the elements in the sequence.        /// </summary>        /// <returns>A new enumerator instance used to enumerate the elements in the sequence.</returns>        public IAsyncEnumerator<T> GetAsyncEnumerator()        {            if (_enumerable == null)            {                var expression = Expression.Lambda<Func<IAsyncEnumerable<T>>>(new AsyncEnumerableRewriter().Visit(_expression), null);                _enumerable = expression.Compile()();            }            return _enumerable.GetAsyncEnumerator();        }        /// <summary>        /// Gets a string representation of the enumerable sequence.        /// </summary>        /// <returns>String representation of the enumerable sequence.</returns>        public override string ToString()        {            var ce = _expression as ConstantExpression;            if (ce == null || ce.Value != this)            {                return _expression.ToString();            }            if (_enumerable != null)            {                return _enumerable.ToString();            }            return "null";        }    }}
 |