/// <summary>
    /// Generates the cached string expression.
    /// </summary>
    /// <returns>System.Linq.Expressions.Expression.</returns>
    /// <remarks>Since it is not possible for this node to be a constant node, the function <see cref="object.ToString"/> is called in whatever the node outputs.</remarks>
    public sealed override Expression GenerateCachedStringExpression()
    {
        var expression = GenerateExpression();

        if (expression.Type == typeof(string))
        {
            return(expression);
        }

        var stringFormatters = SpecialObjectRequestFunction?.Invoke(typeof(IStringFormatter)) as List <IStringFormatter>;

        return(StringFormatter.CreateStringConversionExpression(
                   expression,
                   stringFormatters));
    }
    /// <summary>
    /// Compiles this instance.
    /// </summary>
    /// <returns>A LINQ expression representing the parameter.</returns>
    /// <exception cref="InvalidOperationException">The parameter was already compiled, but it is <see langword="null"/>.</exception>
    /// <exception cref="ExpressionNotValidLogicallyException">The parameter is still undefined.</exception>
    public Expression Compile()
    {
        if (alreadyCompiled)
        {
            return(expression ?? throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.ParameterAlreadyCompiledButCompilationIsNull, Name)));
        }

        Type type;

        switch (ReturnType)
        {
        case SupportedValueType.Boolean:
            type = FuncParameter ? typeof(Func <bool>) : typeof(bool);
            break;

        case SupportedValueType.ByteArray:
            type = FuncParameter ? typeof(Func <byte[]>) : typeof(byte[]);
            break;

        case SupportedValueType.String:
            type = FuncParameter ? typeof(Func <string>) : typeof(string);
            break;

        case SupportedValueType.Numeric:
            if (IsFloat == false)
            {
                type = FuncParameter ? typeof(Func <long>) : typeof(long);
            }
            else
            {
                type = FuncParameter ? typeof(Func <double>) : typeof(double);
            }

            break;

        default:
            throw new ExpressionNotValidLogicallyException();
        }

        ParameterExpression parameterExpression = Expression.Parameter(type, Name);

        parameterDefinitionExpression = parameterExpression;

        if (FuncParameter)
        {
            expression = Expression.Invoke(parameterExpression);
        }
        else
        {
            expression = parameterExpression;
        }

        stringExpression = (ReturnType == SupportedValueType.String)
            ? expression
            : StringFormatter.CreateStringConversionExpression(
            expression,
            stringFormatters);

        alreadyCompiled = true;
        return(expression);
    }