Пример #1
0
        /// <summary>
        /// Binds expression to concrete types and compiles it afterward.
        /// </summary>
        /// <typeparam name="Arg1T">First argument type.</typeparam>
        /// <typeparam name="Arg2T">Second argument type.</typeparam>
        /// <typeparam name="Arg3T">Third argument type.</typeparam>
        /// <typeparam name="Arg4T">Fourth argument type.</typeparam>
        /// <typeparam name="ResultT">Result type.</typeparam>
        /// <param name="arg1Name">First argument name or <see cref="CSharpExpression.ARG1_DEFAULT_NAME"/> if not specified.</param>
        /// <param name="arg2Name">Second argument name or <see cref="CSharpExpression.ARG2_DEFAULT_NAME"/> if not specified.</param>
        /// <param name="arg3Name">Third argument name or <see cref="CSharpExpression.ARG3_DEFAULT_NAME"/> if not specified.</param>
        /// <param name="arg4Name">Fourth argument name or <see cref="CSharpExpression.ARG4_DEFAULT_NAME"/> if not specified.</param>
        /// <returns>Bound and compiled into <see cref="Func{Arg1T, Arg2T, Arg3T, Arg4T, ResultT}"/> expression.</returns>
        public Func <Arg1T, Arg2T, Arg3T, Arg4T, ResultT> Bind <Arg1T, Arg2T, Arg3T, Arg4T, ResultT>(string arg1Name = null, string arg2Name = null, string arg3Name = null, string arg4Name = null)
        {
            var key = new MethodCallSignature
                      (
                typeof(Arg1T),
                arg1Name ?? CSharpExpression.ARG1_DEFAULT_NAME, typeof(Arg2T),
                arg2Name ?? CSharpExpression.ARG2_DEFAULT_NAME, typeof(Arg3T),
                arg3Name ?? CSharpExpression.ARG3_DEFAULT_NAME, typeof(Arg4T),
                arg4Name ?? CSharpExpression.ARG4_DEFAULT_NAME, typeof(ResultT)
                      );
            var expression = default(Expression);

            lock (this.compiledExpressions)
            {
                if (!this.compiledExpressions.TryGetValue(key, out expression))
                {
                    var parameters = CreateParameters
                                     (
                        new[] { typeof(Arg1T), typeof(Arg2T), typeof(Arg3T), typeof(Arg4T) },
                        new[]
                    {
                        arg1Name ?? CSharpExpression.ARG1_DEFAULT_NAME,
                        arg2Name ?? CSharpExpression.ARG2_DEFAULT_NAME,
                        arg3Name ?? CSharpExpression.ARG3_DEFAULT_NAME,
                        arg4Name ?? CSharpExpression.ARG4_DEFAULT_NAME
                    }
                                     );
                    var builder = new Binder(parameters, resultType: typeof(ResultT));
                    expression = builder.Bind(this.SyntaxTree);
                    this.compiledExpressions.Add(key, expression);
                }
            }
            return(((Expression <Func <Arg1T, Arg2T, Arg3T, Arg4T, ResultT> >)expression).CompileAot());
        }
Пример #2
0
            private static InvokeOperation TryCreateInstanceMethod(MethodInfo method)
            {
                if (method.DeclaringType == null)
                {
                    return(null);
                }

                // try get from cache
                var invoker = default(InvokeOperation);

                lock (InstanceMethods)
                    if (InstanceMethods.TryGetValue(method, out invoker))
                    {
                        return(invoker);
                    }

                var creatorsByParamsCount = default(Dictionary <MethodCallSignature, InvokeOperationCreator>[]);

                lock (InstanceMethodCreators)
                    if (InstanceMethodCreators.TryGetValue(method.DeclaringType, out creatorsByParamsCount) == false || creatorsByParamsCount == null)
                    {
                        goto cacheAndReturn;
                    }

                var methodCallSignature = new MethodCallSignature(method);

                if (creatorsByParamsCount.Length < methodCallSignature.Count || creatorsByParamsCount[methodCallSignature.Count] == null)
                {
                    goto cacheAndReturn;
                }

                var creatorsBySignature = creatorsByParamsCount[methodCallSignature.Count];
                var creator             = default(InvokeOperationCreator);

                lock (creatorsBySignature)
                    if (creatorsBySignature.TryGetValue(methodCallSignature, out creator) == false || creator == null)
                    {
                        goto cacheAndReturn;
                    }

                invoker = creator(method, method.GetParameters());

cacheAndReturn:
                // cache it
                lock (InstanceMethods)
                    InstanceMethods[method] = invoker;

                return(invoker);
            }
Пример #3
0
        public Func <Arg1T, Arg2T, Arg3T, ResultT> Bind <Arg1T, Arg2T, Arg3T, ResultT>(string arg1Name = null, string arg2Name = null, string arg3Name = null)
        {
            var key        = new MethodCallSignature(typeof(Arg1T), arg1Name ?? "arg1", typeof(Arg2T), arg2Name ?? "arg2", typeof(Arg3T), arg3Name ?? "arg3", typeof(ResultT));
            var expression = default(Expression);

            lock (this.compiledExpressions)
            {
                if (!this.compiledExpressions.TryGetValue(key, out expression))
                {
                    var parameters = CreateParameters(new[] { typeof(Arg1T), typeof(Arg2T), typeof(Arg3T) }, new[] { arg1Name ?? "arg1", arg2Name ?? "arg2", arg3Name ?? "arg3" });
                    var builder    = new ExpressionBuilder(parameters, resultType: typeof(ResultT));
                    expression = Expression.Lambda <Func <Arg1T, Arg2T, Arg3T, ResultT> >(builder.Build(this.ExpressionTree), parameters);
                    this.compiledExpressions.Add(key, expression);
                }
            }
            return(((Expression <Func <Arg1T, Arg2T, Arg3T, ResultT> >)expression).CompileAot());
        }
Пример #4
0
        /// <summary>
        /// Binds expression to concrete types and compiles it afterward.
        /// </summary>
        /// <typeparam name="ResultT">Result type.</typeparam>
        /// <returns>Bound and compiled into <see cref="Func{ResultT}"/> expression.</returns>
        public Func <ResultT> Bind <ResultT>()
        {
            var key        = new MethodCallSignature(typeof(ResultT));
            var expression = default(Expression);

            lock (this.compiledExpressions)
            {
                if (!this.compiledExpressions.TryGetValue(key, out expression))
                {
                    var parameters = new ReadOnlyCollection <ParameterExpression>(new ParameterExpression[0]);
                    var builder    = new Binder(parameters, resultType: typeof(ResultT));
                    expression = builder.Bind(this.SyntaxTree);
                    this.compiledExpressions.Add(key, expression);
                }
            }

            return(((Expression <Func <ResultT> >)expression).CompileAot());
        }
Пример #5
0
            public static void RegisterInstanceMethod <InstanceT, ResultT>()
            {
                const int PARAMS_INDEX = 0;

                var creatorsByParamsCount = default(Dictionary <MethodCallSignature, InvokeOperationCreator>[]);

                lock (InstanceMethodCreators)
                    if (InstanceMethodCreators.TryGetValue(typeof(InstanceT), out creatorsByParamsCount) == false)
                    {
                        InstanceMethodCreators[typeof(InstanceT)] = creatorsByParamsCount = new Dictionary <MethodCallSignature, InvokeOperationCreator> [4];
                    }

                var creatorsBySignature = creatorsByParamsCount[PARAMS_INDEX];

                if (creatorsBySignature == null)
                {
                    creatorsByParamsCount[PARAMS_INDEX] = creatorsBySignature = new Dictionary <MethodCallSignature, InvokeOperationCreator>();
                }

                var methodCallSignature = new MethodCallSignature(typeof(ResultT));

                lock (creatorsBySignature)
                    creatorsBySignature[methodCallSignature] = new InvokeOperationCreator(TryCreate <InstanceT, ResultT>);
            }