/// <summary> /// Generates a static binary function call with explicit parameter types. /// </summary> /// <typeparam name="TParam1">The type of the first parameter.</typeparam> /// <typeparam name="TParam2">The type of the second parameter.</typeparam> /// <param name="t">The type to call on.</param> /// <param name="functionName">Name of the function.</param> /// <param name="tolerance">The tolerance, should there be any. This argument can be <c>null</c> (<c>Nothing</c> in Visual Basic).</param> /// <returns> /// The generated binary method call expression. /// </returns> /// <exception cref="ArgumentException">The function name is invalid.</exception> protected Expression GenerateStaticBinaryFunctionCall <TParam1, TParam2>(Type t, string functionName, Tolerance?tolerance) { if (string.IsNullOrWhiteSpace(functionName)) { throw new ArgumentException(string.Format(Resources.FunctionCouldNotBeFound, functionName), nameof(functionName)); } Type firstParameterType = ParameterTypeFromParameter(FirstParameter); Type secondParameterType = ParameterTypeFromParameter(SecondParameter); MethodInfo mi = t.GetMethodWithExactParameters(functionName, typeof(TParam1), typeof(TParam2)) ?? throw new FunctionCallNotValidLogicallyException(); Expression e1, e2; if (tolerance == null) { e1 = FirstParameter.GenerateExpression(); e2 = SecondParameter.GenerateExpression(); } else { e1 = FirstParameter.GenerateExpression(tolerance); e2 = SecondParameter.GenerateExpression(tolerance); } if (e1.Type != firstParameterType) { e1 = Expression.Convert(e1, firstParameterType); } if (e2.Type != secondParameterType) { e2 = Expression.Convert(e2, secondParameterType); } if (e1.Type != typeof(TParam1)) { e1 = Expression.Convert(e1, typeof(TParam1)); } if (e2.Type != typeof(TParam2)) { e2 = Expression.Convert(e2, typeof(TParam2)); } return(Expression.Call(mi, e1, e2)); }
/// <summary> /// Generates the expression with tolerance that will be compiled into code. /// </summary> /// <param name="tolerance">The tolerance.</param> /// <returns>The expression.</returns> protected override Expression GenerateExpressionInternal(Tolerance?tolerance) { Type firstParameterType = typeof(string); Type secondParameterType = typeof(int); Type thirdParameterType = typeof(int); const string functionName = nameof(string.Substring); MethodInfo mi = typeof(string).GetMethodWithExactParameters( functionName, secondParameterType, thirdParameterType) !; if (mi == null) { throw new InvalidOperationException( string.Format( CultureInfo.CurrentCulture, Resources.FunctionCouldNotBeFound, functionName)); } Expression e1, e2, e3; if (tolerance == null) { e1 = FirstParameter.GenerateExpression(); e2 = SecondParameter.GenerateExpression(); e3 = ThirdParameter.GenerateExpression(); } else { e1 = FirstParameter.GenerateExpression(tolerance); e2 = SecondParameter.GenerateExpression(tolerance); e3 = ThirdParameter.GenerateExpression(tolerance); } if (e1.Type != firstParameterType) { e1 = Expression.Convert( e1, firstParameterType); } if (e2.Type != secondParameterType) { e2 = Expression.Convert( e2, secondParameterType); } if (e3.Type != thirdParameterType) { e3 = Expression.Convert( e3, thirdParameterType); } return(Expression.Call( e1, mi, e2, e3)); }
/// <summary> /// Generates a static binary function call expression. /// </summary> /// <param name="t">The type to call on.</param> /// <param name="functionName">Name of the function.</param> /// <param name="tolerance">The tolerance, should there be any. This argument can be <c>null</c> (<c>Nothing</c> in Visual Basic).</param> /// <returns> /// Expression. /// </returns> /// <exception cref="ArgumentException">The function name is invalid.</exception> protected Expression GenerateBinaryFunctionCallFirstParameterInstance(Type t, string functionName, Tolerance?tolerance) { if (string.IsNullOrWhiteSpace(functionName)) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.FunctionCouldNotBeFound, functionName), nameof(functionName)); } Type firstParameterType = ParameterTypeFromParameter(FirstParameter); Type secondParameterType = ParameterTypeFromParameter(SecondParameter); MethodInfo?mi = t.GetMethodWithExactParameters(functionName, firstParameterType, secondParameterType); if (mi == null) { if ((firstParameterType == typeof(long) && secondParameterType == typeof(double)) || (firstParameterType == typeof(double) && secondParameterType == typeof(long))) { firstParameterType = typeof(double); secondParameterType = typeof(double); mi = t.GetMethodWithExactParameters(functionName, firstParameterType, secondParameterType); if (mi == null) { firstParameterType = typeof(long); secondParameterType = typeof(long); mi = t.GetMethodWithExactParameters(functionName, firstParameterType, secondParameterType); if (mi == null) { firstParameterType = typeof(int); secondParameterType = typeof(int); mi = t.GetMethodWithExactParameters(functionName, firstParameterType, secondParameterType) ?? throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.FunctionCouldNotBeFound, functionName), nameof(functionName)); } } } else { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.FunctionCouldNotBeFound, functionName), nameof(functionName)); } } Expression e1, e2; if (tolerance == null) { e1 = FirstParameter.GenerateExpression(); e2 = SecondParameter.GenerateExpression(); } else { e1 = FirstParameter.GenerateExpression(tolerance); e2 = SecondParameter.GenerateExpression(tolerance); } if (e1.Type != firstParameterType) { e1 = Expression.Convert(e1, firstParameterType); } if (e2.Type != secondParameterType) { e2 = Expression.Convert(e2, secondParameterType); } return(Expression.Call(e1, mi, e2)); }