Как получить значение из анонимного выражения?
Для простоты представьте себе следующий код:
Я хочу создать Foo:
public class Foo
{
public string Bar { get; set; }
}
И передайте его специальному методу Html Helper:
Html.SomeFunction(f => f.Bar);
Определяется как:
public string SomeFunction<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
Я хочу получить значение Bar внутри этой функции, но понятия не имею, как ее получить.
Ответы
Ответ 1
Просто скомпилируйте выражение и получите значение.
Func<TModel, TValue> method = expression.Compile();
TValue value = method(html.ViewData.Model);
// might be a slightly different property, but you can get the ViewModel
// from the HtmlHelper object.
Ответ 2
Вам нужно будет вызвать Compile()
в выражении, чтобы получить Func, а затем выполнить его.
public string SomeFunction<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
{
TValue valueOfBar = expression.Compile()(html.Model); // Assumes Model is accessible from html.
// Do stuff
}
Боковое примечание. Если нет необходимости в динамических выражениях или анализе выражения, вы можете также передать Func непосредственно.
Ответ 3
Для тех, кто использует выражение без MVT Model, можно получить имя и значение свойства следующим образом.
public static string Meth<T>(Expression<Func<T>> expression)
{
var name = ((MemberExpression)expression.Body).Member.Name;
var value = expression.Compile()();
return string.Format("{0} - {1}", name, value);
}
использование:
Meth(() => YourObject.Property);
Ответ 4
Использование Compile()
будет использовать структуру компилятора Roslyn и выпустить MSIL-код, который будет динамически загружен в ваше приложение. Этот исполняемый код занимает память, и в отличие от "нормальной" памяти он не подлежит сборке мусора, и вы не можете его самостоятельно освободить. Если вы делаете это слишком часто (например, регулярно во время генерации SQL), в конечном итоге у вас закончится нехватка памяти. Я столкнулся с этой проблемой и открыл свои решения в виде библиотеки с открытым исходным кодом:
https://www.nuget.org/packages/MiaPlaza.ExpressionUtils