2011-04-05 16 views
14

爲了簡單起見,假設下面的代碼:如何從匿名錶達式獲取值?

我想創建一個Foo:

public class Foo 
{ 
    public string Bar { get; set; } 
} 

並將它傳遞給一個特殊的HTML輔助方法:

Html.SomeFunction(f => f.Bar); 

其定義作爲:

public string SomeFunction<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression) 

我想獲得酒吧裏面的值這個功能,但絕對不知道如何得到它。

回答

26

只需編譯表達式並獲取值。

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. 
+0

我的代碼中出現以下錯誤:錯誤'System.Web.Mvc.HtmlHelper '未包含'Model'的定義,也沒有可以找到擴展方法'Model'接受'System.Web.Mvc.HtmlHelper '類型的第一個參數(你是否缺少using指令或程序集引用?) – mynameiscoffey 2011-04-05 19:28:30

+2

它應該是'html.ViewData.Model'。我最初的帖子只是急於使用屬性名稱。 – Tejs 2011-04-05 19:29:39

+0

+1作品像一個魅力,謝謝! – mynameiscoffey 2011-04-05 19:32:22

5

您需要在表達式上調用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直接傳入。

+1

+1 Reddog也講真話這裏;如果實際上沒有理由檢查表達式,那麼只需傳遞'Func '好得多。 – Tejs 2011-04-05 19:26:14

+1

不幸的是,表達式是方法內發生的其他交互所必需的 – mynameiscoffey 2011-04-05 19:30:10

0

對於那些使用無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); 
0

使用Compile()將使用羅斯林編譯器框架,並將發出MSIL代碼將被動態加載到你的應用程序。這個可執行代碼佔用內存,與「普通」內存不同,它不受垃圾收集限制,也不能自由釋放內存。如果你頻繁地執行此操作(如在SQL生成期間定期執行),最終會導致內存不足。我就遇到了這個問題,開源解決方案,我作爲一個開放源碼庫:

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