public MethodBuilder DefineMethod( string methodName, ParameterExpression[] paramExprs, Expression bodyExpr, MethodAttributes methodAttributes = MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions callingConventions = CallingConventions.Standard | CallingConventions.HasThis) { if (paramExprs == null) { paramExprs = Array.Empty <ParameterExpression>(); } Type[] paramTypes = new Type[paramExprs.Length]; string[] paramNames = new string[paramExprs.Length]; for (int i = 0; i < paramExprs.Length; i++) { paramTypes[i] = paramExprs[i].Type; paramNames[i] = paramExprs[i].Name; } if (callingConventions.HasFlag(CallingConventions.HasThis)) { ParameterExpression[] newParams = new ParameterExpression[paramExprs.Length + 1]; newParams[0] = This; Array.Copy(paramExprs, 0, newParams, 1, paramExprs.Length); paramExprs = newParams; } MethodBuilder newMethod = TypeBuilder.DefineMethod( methodName, methodAttributes, callingConventions, bodyExpr.Type, paramTypes); for (int i = 0; i < paramTypes.Length; i++) { newMethod.DefineParameter(i, ParameterAttributes.None, paramNames[i]); } bool success = ExpressionCompiler.CompileForTypeBuilder(paramExprs, bodyExpr, bodyExpr.Type, newMethod.GetILGenerator(), true); if (!success) { throw new InvalidOperationException($"Can't compile method"); } Methods.Add(new RuntimeTypeMethod(methodName, newMethod, paramTypes, bodyExpr.Type)); return(newMethod); }