मैं अभिव्यक्ति वृक्ष बना रहा हूं और ऐसी स्थिति है जहां मुझे एक अन्य लैम्ब्डा में एक लैम्ब्डा बनाने और कक्षा में आंतरिक स्टोर करने की आवश्यकता है और अभिव्यक्ति के पेड़ में उस वर्ग को जोड़ना है। यह मुझे क्या करना है कोशिश कर रहा हूँ की सरल उदाहरण है (इस कोड संकलन नहीं करता है):अभिव्यक्ति वृक्ष - बाहरी लैम्ब्डा में आंतरिक लैम्ब्डा संकलित करें - स्कॉइंग रिज़ॉल्यूशन
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
namespace SimpleTest {
public class LambdaWrapper {
private Delegate compiledLambda;
public LambdaWrapper(Delegate compiledLambda) {
this.compiledLambda = compiledLambda;
}
public dynamic Execute() {
return compiledLambda.DynamicInvoke();
}
}
public class ForSO {
public ParameterExpression Param;
public LambdaExpression GetOuterLambda() {
IList<Expression> lambdaBody = new List<Expression>();
Param = Expression.Parameter(typeof(object), "Param");
lambdaBody.Add(Expression.Assign(
Param,
Expression.Constant("Value of 'param' valiable"))
);
lambdaBody.Add(Expression.Call(
null,
typeof(ForSO).GetMethod("Write"),
Param)
);
Delegate compiledInnerLambda = GetInnerLambda().Compile();
LambdaWrapper wrapper = new LambdaWrapper(compiledInnerLambda);
lambdaBody.Add(Expression.Constant(wrapper));
//lambdaBody.Add(GetInnerLambda());
return Expression.Lambda(
Expression.Block(
new ParameterExpression[] { Param },
lambdaBody));
}
public LambdaExpression GetInnerLambda() {
return Expression.Lambda(
Expression.Block(
Expression.Call(null,
typeof(ForSO).GetMethod("Write"),
Expression.Constant("Inner lambda start")),
Expression.Call(null,
typeof(ForSO).GetMethod("Write"),
Param),
Expression.Call(null,
typeof(ForSO).GetMethod("Write"),
Expression.Constant("Inner lambda end"))
)
);
}
public static void Write(object toWrite) {
Console.WriteLine(toWrite);
}
public static void Main(string[] args) {
ForSO so = new ForSO();
LambdaWrapper wrapper = so.GetOuterLambda().Compile()
.DynamicInvoke() as LambdaWrapper;
wrapper.Execute();
//(so.GetOuterLambda().Compile().DynamicInvoke() as Delegate).DynamicInvoke();
}
}
}
समस्या GetOuterLambda
विधि में GetInnerLambda().Compile()
कतार में है। मुझे एक समाधान के बारे में पता है - यह कोड के हिस्से में टिप्पणी की गई है। इसके साथ, सबकुछ ठीक काम करता है, लेकिन मुझे रिटर्न वैल्यू के रूप में एक रैपर की आवश्यकता होती है, अभिव्यक्ति subtree नहीं (यह LambdaWrapper में आंतरिक लैम्ब्डा सबट्री स्टोर करना ठीक हो सकता है, और इसे बाद में संकलित कर सकता है, लेकिन एक ही समस्या होती है)।
मुझे जो त्रुटि मिल रही है वह Unhandled Exception: System.InvalidOperationException: variable 'Param' of type 'System.Object' referenced from scope '', but it is not defined
है।
यदि मैं आंतरिक लैम्ब्डा में चर को अवरुद्ध करने के लिए Param
जोड़ता हूं, तो कोड संकलित करता है, लेकिन परम बाहरी लैम्ब्डा (और यह समझ में आता है) में असाइन किया गया मान नहीं है।
यह कैसे हल किया जा सकता है? अपने LambdaWrapper
में
public LambdaExpression GetInnerLambda()
{
var param = Expression.Parameter(typeof(object));
return Expression.Lambda(
Expression.Block(
Expression.Call(null,
typeof(ForSO).GetMethod("Write"),
Expression.Constant("Inner lambda start")),
Expression.Call(null,
typeof(ForSO).GetMethod("Write"),
param),
Expression.Call(null,
typeof(ForSO).GetMethod("Write"),
Expression.Constant("Inner lambda end"))
),
param
);
}
तब पैरामीटर का मान संग्रहीत:
जवाब के लिए धन्यवाद।मुझे इस दृष्टिकोण के बारे में क्या पसंद नहीं है यह है कि वे लैम्बडा वास्तविक कार्य हैं, और उनके पास पैरामीटर हो सकते हैं (मैंने उस भाग को प्रश्न में शामिल नहीं किया क्योंकि मुझे इसमें कोई समस्या नहीं है), और परम न केवल परिवर्तनीय मुझे एक्सेस करने की आवश्यकता है (उनमें से बहुत कुछ हो सकता है), इसलिए मुझे नहीं लगता कि स्कोपिंग को हल करने के लिए एडिग कृत्रिम पैरामीटर बहुत ही सुरुचिपूर्ण समाधान है। –
अपडेट किया गया उत्तर सिर्फ मेरे लिए काम कर सकता है, लेकिन मुझे यह जांचना होगा कि मैं अपने कामकाजी कंप्यूटर पर वापस कब आऊंगा। धन्यवाद ... –
मैंने जांच की कि यह मेरे लिए काम करता है या नहीं। लगभग :)। मैंने इसे एक कदम आगे ले लिया और LambdaWrapper के उदाहरण बनाने के लिए डायनामिक एक्स्प्रेशन बनाया। मुझे बाइंडर्स बनाना पड़ा, इसलिए इस आत्मा को अधिक काम की आवश्यकता है, लेकिन मेरे पास पहले से ही मेरे मुख्य प्रोजेक्ट में था। इस मुद्दे को हल करने में आपके द्वारा दिखाए गए ब्याज के लिए धन्यवाद :) –