के साथ प्रतिनिधि में लैम्ब्डा अभिव्यक्ति के परिणाम संकलित करते समय जब मैं अभिव्यक्ति वृक्ष से प्रतिनिधि बनाने के लिए Expression.Lambda(...).Compile()
का उपयोग करता हूं, तो परिणाम एक प्रतिनिधि होता है जिसमें पहला तर्क Closure
होता है।क्लोजर तर्क
public static Func<T, T, T> CreateTest<T>()
{
ParameterExpression a = Expression.Parameter(typeof(T));
ParameterExpression b = Expression.Parameter(typeof(T));
Expression addition = Expression.Add(a, b);
return (Func<T, T, T>)Expression.Lambda(addition, a, b).Compile();
}
...
// 'addition' equals
// Int32 lambda_method(
// System.Runtime.CompilerServices.Closure,
// Int32,
// Int32)
Func<int, int, int> addition = DelegateHelper.CreateTest<int>();
int result = addition(5, 5);
मैं आसानी से एक Closure
वस्तु गुजर बिना साधारण कोड के माध्यम से प्रतिनिधि कॉल कर सकते हैं, लेकिन जहां इस Closure
से आता है?
मैं इस प्रतिनिधि को गतिशील रूप से कैसे कॉल कर सकता हूं?
// The following does not work.
// Exception: MethodInfo must be a runtime MethodInfo object.
MethodInfo additionMethod = addition.Method;
int result = (int)additionMethod.Invoke(null, new object[] { 5, 5 });
अभिव्यक्ति के पेड़ का उपयोग यह है कि मैं Closure
वस्तु पारित करने के लिए है लग रहा है।
PropertyInfo methodProperty
= typeof(Delegate).GetProperty("Method", typeof(MethodInfo));
MemberExpression getDelegateMethod
= Expression.Property(Expression.Constant(addition), methodProperty);
Func<MethodInfo> getMethodInfo
= (Func<MethodInfo>)Expression.Lambda(getDelegateMethod).Compile();
// Incorrect number of arguments supplied for call to method
// 'Int32 lambda_method(System.Runtime.CompilerServices.Closure, Int32, Int32)'
Expression call
= Expression.Call(
getMethodInfo(),
Expression.Constant(5), Expression.Constant(5));
इस सरल उदाहरण से जो अपने आप में कोई मतलब नहीं है है। जो मैं वास्तव में प्राप्त करने की कोशिश कर रहा हूं वह है लपेटने में सक्षम होना Func<Action<object>>
के साथ। मैं पहले से ही गैर घोंसले प्रतिनिधियों के लिए ऐसा कर सकता हूं। यह प्रतिबिंब के दौरान उपयोगी है, as discussed here।
मुझे इस Closure
ऑब्जेक्ट को सही तरीके से कैसे प्रारंभ करना चाहिए, या मैं इसे वहां से कैसे रोकूं?
क्या आप एक छोटा लेकिन पूरा * उदाहरण दे सकते हैं? यह वास्तव में स्पष्ट नहीं है कि समस्या क्या है। –
@ जोनस्केट: मैं अपनी पूरी कोशिश करूंगा, समस्या यह है कि कुल उदाहरण काफी जटिल है। मैं पहले से संकलित प्रतिनिधि को दोबारा कॉल करने का प्रयास कर रहा हूं। जबकि मैं समस्या का एक छोटा सबसेट निकालने का प्रयास करता हूं, [यहां] (http://pastebin.com/53f0VqnF) आप पहले से ही संपूर्ण फ़ंक्शन पा सकते हैं। –
हाँ, इसे कम करने में निश्चित रूप से मदद मिलेगी :) –