如何从匿名表达式中获取值

本文关键字:获取 表达式 | 更新日期: 2023-09-27 17:48:58

为简单起见,想象如下代码:

我想创建一个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的值,但是完全不知道如何得到它

如何从匿名表达式中获取值

只需编译表达式并获取值。

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. 

您需要在表达式上调用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

对于不使用MVT模型的表达式,可以通过以下方式获取属性的名称和值。

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

在Microsoft.AspNetCore.Mvc.Rendering there is helpfull valuefor method;

公共静态字符串valuefortmodel, TResult>(this IHtmlHelper, htmlHelper, Expression<TModel,>>;

表达式);
public string SomeFunction<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression){
var valueOfExpression = html.ValueFor(expression); 
//do your stuff
}

使用Compile()将使用Roslyn编译器框架,并将发出将动态加载到应用程序中的msil代码。此可执行代码占用内存,与"正常"内存相比,它不受垃圾收集的约束,也不能自己释放它。如果过于频繁地这样做(比如在SQL生成过程中经常这样做),最终会耗尽内存。我遇到了这个问题,并将我的解决方案开源为开源库:

https://www.nuget.org/packages/MiaPlaza.ExpressionUtils