/// <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()); }
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); }
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()); }
/// <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()); }
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>); }