2011-04-05 13 views
14

सरलता के लिए, मान लें निम्नलिखित कोड:मैं अज्ञात अभिव्यक्ति से मूल्य कैसे प्राप्त करूं?

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 ' में 'मॉडल' और कोई परिभाषा नहीं है एक्सटेंशन 'मॉडल' प्रकार का पहला तर्क स्वीकार कर रहा है 'System.Web.Mvc.HtmlHelper ' पाया जा सकता है (क्या आप एक निर्देश या निर्देशक संदर्भ का उपयोग कर रहे हैं?) – mynameiscoffey

+2

यह 'html.ViewData.Model' होना चाहिए। मेरी प्रारंभिक पोस्ट बस संपत्ति के नाम से जल्दबाजी में थी। – Tejs

+0

+1 एक आकर्षण की तरह काम करता है, धन्यवाद !! – mynameiscoffey

5

आपको Func प्राप्त करने के लिए अभिव्यक्ति पर Compile() पर कॉल करने की आवश्यकता होगी और फिर उसे निष्पादित करें।

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

+1

दुर्भाग्यवश – mynameiscoffey

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-कोड जो गतिशील रूप से अपने आवेदन में लोड किया जाएगा फेंकना होगा। यह निष्पादन योग्य कोड स्मृति लेता है, और "सामान्य" स्मृति के विपरीत यह कचरा संग्रह के अधीन नहीं है और न ही आप इसे स्वयं मुक्त कर सकते हैं। यदि आप इसे अक्सर करते हैं (जैसे नियमित रूप से एसक्यूएल पीढ़ी के दौरान) आप अंततः स्मृति से बाहर हो जाएंगे। मैं इस मुद्दे में भाग गया और एक खुला स्रोत पुस्तकालय के रूप में मेरे समाधान मुक्त-स्रोत:

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

संबंधित मुद्दे