public string Calcul <T>(T data, LambdaExpression query, string format)
        {
            query = (LambdaExpression)ExpressionPreProcessor.PreProcessor(data, query);

            var rulesCheckerResult = RulesChecker.Check(data, query);

            if (rulesCheckerResult.HasManquante)
            {
                return(TypeDonnee.Manquante.ReportValue);
            }

            if (rulesCheckerResult.HasDivisionParZero)
            {
                return(TypeDonnee.DivisionParZero.ReportValue);
            }

            if (rulesCheckerResult.HasNonDiffusable)
            {
                return(TypeDonnee.NonDiffusable.ReportValue);
            }

            if (rulesCheckerResult.HasConfidentielle)
            {
                return(TypeDonnee.Confidentielle.ReportValue);
            }

            Delegate lambda = query.Compile();
            decimal? result = (decimal?)lambda.DynamicInvoke(data);

            return(result != null
                    ? result.Value.ToString(format)
                    : TypeDonnee.Manquante.ReportValue);
        }
        private bool HasIssue(object data, LambdaExpression query, out string reportValue)
        {
            reportValue = null;

            var rulesCheckerResult = RulesChecker.Check(data, query);

            if (rulesCheckerResult.HasManquante)
            {
                reportValue = TypeDonnee.Manquante.ReportValue;
            }

            if (rulesCheckerResult.HasDivisionParZero)
            {
                reportValue = TypeDonnee.DivisionParZero.ReportValue;
            }

            if (rulesCheckerResult.HasNonDiffusable)
            {
                reportValue = TypeDonnee.NonDiffusable.ReportValue;
            }

            if (rulesCheckerResult.HasConfidentielle)
            {
                reportValue = TypeDonnee.Confidentielle.ReportValue;
            }

            return(reportValue != null);
        }
        static void Main()
        {
            var value1 = 1;
            var value2 = 2;
            var value3 = new { MyValue = 3 };
            var data   = new DataInfo {
                A = 10, B = 1, C = -1
            };

            Expression <Func <DataInfo, decimal?> > expression = x => x.A / (x.B + x.C) + (value1 + value2) + value3.MyValue;

            // create a list of variables that will be used when evaluating the expression
            var variables = new Dictionary <Type, object>();

            // add the root object
            variables.Add(data.GetType(), data);

            // find variables that are referenced in the expression
            var finder = new VariablesFinder(variables);

            finder.Visit(expression);

            // replace variables with ConstantExpressions
            var visitor       = new VariableReplacer(variables);
            var newExpression = visitor.Visit(expression);

            var rulesChecker      = new RulesChecker();
            var checkedExpression = rulesChecker.Visit(newExpression);
        }
        private static RulesCheckerResult GetResults(object data, Expression expression)
        {
            var visitor = new RulesChecker(data);

            visitor.Visit(expression);

            return(new RulesCheckerResult(
                       visitor.hasConfidentielle,
                       visitor.hasNonDiffusable,
                       visitor.hasDivisionParZero,
                       visitor.hasManquante));
        }