Вы просто должны обернуть исходное выражение Body
в выражении Convert
, а затем перестроить свою лямбду. Вот как я бы это сделать, если я мог дженерики использование:
Expression<Func<TInput, TReturn>> ConvertReturnValue<TInput, TReturn>(
Expression<Func<TInput, object>> inputExpression)
{
Expression convertedExpressionBody = Expression.Convert(
inputExpression.Body, typeof(TReturn)
);
return Expression.Lambda<Func<TInput, TReturn>>(
convertedExpressionBody, inputExpression.Parameters
);
}
Использование:
Expression<Func<TDocument, object>> inputExpression = d => d.Name;
Expression<Func<TDocument, string>> convertedExpression
= ConvertReturnValue<TDocument, string>(inputExpression);
// Test.
TDocument doc = new TDocument { Name = "Zzz" };
string name = convertedExpression.Compile().Invoke(doc);
Assert.Equal("Zzz", name);
Нет дженерики
Если вы не можете использовать дженерики, потому что вы не знаете, возвращаемый тип во время компиляции, Expression.Lambda
фактически предлагает неосновную перегрузку, которую вы можете использовать следующим образом:
Expression ConvertReturnValue<TInput>(Expression<Func<TInput, object>> inputExpression, Type returnType)
{
Expression convertedExpressionBody = Expression.Convert(inputExpression.Body, returnType);
return Expression.Lambda(convertedExpressionBody, inputExpression.Parameters);
}
Вышеупомянутое все еще возвращает Expression<Func<TInput, TReturn>>
(upcast для не общего Expression
). Вы можете обратное приведение его позже, если вам нужно:
Expression<Func<TDocument, object>> inputExpression = d => d.Name;
Expression<Func<TDocument, string>> convertedExpression
= (Expression<Func<TDocument, string>>)ConvertReturnValue(inputExpression, typeof(string));
// Test.
TDocument doc = new TDocument { Name = "Zzz" };
string name = convertedExpression.Compile().Invoke(doc);
Assert.Equal("Zzz", name);
Добавление
Обратите внимание, что для типов возврата структура, окончательное выражение может в конечном итоге выглядит так:
(TDocument d) => (int)(object)d.ID;
это полезно http://stackoverflow.com/questions/24906609/how-to-get-compile-time-type-of-a-variable –
Извините, но это не так. Не показывает мне, как преобразовать выражение. – Complexity