public override Expression Apply(Expression expression, Random random)
        {
            var typeArgument = expression.Type.GetGenericArguments()[0];

            var isDescending = random.Next(3) == 0;
            var thenBy       = isDescending
                ? ThenByDescendingMethodInfo.MakeGenericMethod(typeArgument, typeArgument)
                : ThenByMethodInfo.MakeGenericMethod(typeArgument, typeArgument);

            var prm              = Expression.Parameter(typeArgument, "prm");
            var lambda           = Expression.Lambda(prm, prm);
            var resultExpression = Expression.Call(thenBy, expression, lambda);

            return(resultExpression);
        }
Exemple #2
0
        public override Expression Apply(Expression expression, Random random)
        {
            var i = random.Next(_expressionFinder.FoundExpressions.Count);
            var expressionToInject = _expressionFinder.FoundExpressions.ToList()[i].Key;
            var j        = random.Next(_expressionFinder.FoundExpressions[expressionToInject].Count);
            var property = _expressionFinder.FoundExpressions[expressionToInject][j];

            var typeArgument = expressionToInject.Type.GetGenericArguments()[0];

            var isDescending = random.Next(3) == 0;
            var thenBy       = isDescending
                ? ThenByDescendingMethodInfo.MakeGenericMethod(typeArgument, property.PropertyType)
                : ThenByMethodInfo.MakeGenericMethod(typeArgument, property.PropertyType);

            var prm        = Expression.Parameter(typeArgument, "prm");
            var lambdaBody = (Expression)Expression.Property(prm, property);

            if (property.PropertyType.IsValueType &&
                !(property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable <>)))
            {
                var nullablePropertyType = typeof(Nullable <>).MakeGenericType(property.PropertyType);

                thenBy = isDescending
                    ? ThenByDescendingMethodInfo.MakeGenericMethod(typeArgument, nullablePropertyType)
                    : ThenByMethodInfo.MakeGenericMethod(typeArgument, nullablePropertyType);

                lambdaBody = Expression.Convert(lambdaBody, nullablePropertyType);
            }

            if (typeArgument == typeof(string))
            {
                // string.Length - make it nullable in case we access optional argument
                thenBy     = OrderByMethodInfo.MakeGenericMethod(typeArgument, typeof(int?));
                lambdaBody = Expression.Convert(lambdaBody, typeof(int?));
            }

            var lambda   = Expression.Lambda(lambdaBody, prm);
            var injector = new ExpressionInjector(expressionToInject, e => Expression.Call(thenBy, e, lambda));

            return(injector.Visit(expression));
        }