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); }
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)); }