C # Есть ли способ разрешить тип делегата лямбда-выражения в коде - PullRequest
2 голосов
/ 24 сентября 2019

Моя цель - поддержать сортировку в приложении и предоставить его через REST API, который будет принимать параметр в виде строки.

Текущая реализация имеет следующие черты:

GetUsers (Expression<Func<User, int>> sortExpression) {
 // Retrieve users ... 
 return users.orderBy(sortExpression);
}

Usage example:
var users = GetUsers(u => u.Id);

Expression<Func<User, int>> sortExpression широко используется в нашем хранилище, и изменить его будет сложно.

Я хотел бы поменять u => u.Id с чем-то, что генерируется во время выполнения.

То, что у меня пока есть:

// sortBy is retrieved from the calling method.
var type = typeof(User).GetProperties().FirstOrDefault(x => x.Name == sortBy).GetType();

var sortExpression = Expression.Property(Expression.Parameter(typeof(User)), sortBy);

var parameter = Expression.Parameter(typeof(User));

var expressionBody = Expression.Lambda(typeof(Func<User, int>), sortExpression, parameter);

var users = GetUsers(expressionBody)

Я могу видеть во время выполнения, что это создает выражение, которое соответствует моим потребностям, но ошибка составляет Argument 5: cannot convert from 'LambdaExpression' to 'Expression<System.Func<User, int>>', хотя тело выражения должно быть установлено typeof(Func<User, int>)

1 Ответ

1 голос
/ 24 сентября 2019

Я понял, что я делаю неправильно.

Первый: создайте тело выражения, используя универсальный метод

// Generic Method, return type Expression<Func<User, int>>
Expression.Lambda<Func<User, int>>(sortExpression, parameter);

Вместо передачи параметра typeof(Func<User, int>).

// Non-generic. Return type LambdaExpression
Expression.Lambda(typeof(Func<User, int>), sortExpression, parameter);

Второй:

Я не связывал параметр должным образом, из-за чего выражение получало доступ к свойству отброшенного параметра, который не был предоставлен выражению.

// I'm creating an expression to access the property of a newly created parameter.
var sortExpression = Expression.Property(Expression.Parameter(typeof(User)), sortBy);
var parameter = Expression.Parameter(typeof(User));
var expressionBody = Expression.Lambda<Func<User, int>>(sortExpression, parameter);

//Above causes an unbinded variable exception since there are two parameters, one of which is not passed/bound.

//Should be:
var parameter = Expression.Parameter(typeof(User));
var sortExpression = Expression.Property(parameter, sortBy);

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...