Example #1
0
        /// <summary>
        /// Creates an <see cref="Expression{TDelegate}" /> where the delegate type is known at compile time.
        /// </summary>
        /// <param name="isAsync">Indicates whether the resulting lambda is synchronous or asynchronous.</param>
        /// <param name="body">An <see cref="Expression" /> representing the body of the lambda.</param>
        /// <param name="parameters">An array of <see cref="ParameterExpression" /> objects that represent the parameters passed to the lambda.</param>
        /// <returns>An expression representing a lambda with the specified body and parameters.</returns>
        public static Expression <TDelegate> Lambda <TDelegate>(bool isAsync, Expression body, params ParameterExpression[] parameters)
        {
            // NB: If we were to omit the isAsync parameter, we could try to check the TDelegate return type and
            //     match it with the body type to determine whether the intent is to create a sync or an async
            //     lambda. However, for a return type of void, it's unclear what the intent is. We could resort
            //     to scanning the body looking for await expressions. None of these techniques aligns well with
            //     the explicitness in the language wrt the async modifier, so we shy away from any such smarts.
            //
            // NB: Ultimately, this overload should likely go away and the language should bind to AsyncLambda in
            //     case of emitting an expression tree for an async lambda. Right now, the overload exists to have
            //     assignment compatibility with Expression<T> for async lambdas, so we don't have to extend the
            //     language with AsyncCSharpExpression<T> as a type to consider for lambda convertibility. Notice
            //     though that the async case here causes an expression tree to be created that's not very natural
            //     to say the least. It does, however, compile and evaluate just fine at runtime. In order to lift
            //     this restriction, we have to either extend LINQ to support async Expression<T> or unseal it to
            //     allow for our library to create derived async variants.

            if (isAsync)
            {
                var async = CSharpExpression.AsyncLambda <TDelegate>(body, parameters);
                return(Expression.Lambda <TDelegate>(Expression.Invoke(async, parameters), parameters));
            }
            else
            {
                return(Expression.Lambda <TDelegate>(body, parameters));
            }
        }
Example #2
0
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="body">The <see cref="AsyncLambdaCSharpExpression.Body" /> property of the result.</param>
        /// <param name="parameters">The <see cref="AsyncLambdaCSharpExpression.Parameters" /> property of the result. </param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public AsyncCSharpExpression <TDelegate> Update(Expression body, IEnumerable <ParameterExpression> parameters)
        {
            if (body == Body && SameElements(ref parameters, Parameters))
            {
                return(this);
            }

            return(CSharpExpression.AsyncLambda <TDelegate>(body, parameters));
        }
Example #3
0
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="body">The <see cref="AsyncLambdaCSharpExpression.Body" /> property of the result.</param>
        /// <param name="parameters">The <see cref="AsyncLambdaCSharpExpression.Parameters" /> property of the result. </param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public AsyncCSharpExpression <TDelegate> Update(Expression body, IEnumerable <ParameterExpression> parameters)
        {
            if (body == base.Body && parameters == base.Parameters)
            {
                return(this);
            }

            return(CSharpExpression.AsyncLambda <TDelegate>(body, parameters));
        }