का उपयोग कर परिचय वस्तु बनानेगतिशील रूप से प्रतिबिंब, श्रृंखलित तरीकों और लैम्ब्डा भाव
मेरा आवेदन विधि श्रृंखलन का उपयोग कर तो यह उत्पन्न होते हैं और इसलिए तरह कॉन्फ़िगर किया गया है एक वस्तु को दर्शाता है:
var car = new Car("Ferrari").Doors(2).OtherProperties(x = x.Color("Red"));
समस्या
मेरे पास एक आवश्यकता है टी को इस ऑब्जेक्ट को रनटाइम पर गतिशील रूप से उत्पन्न करने के लिए - कॉन्फ़िगरेशन के लिए जरूरी जंजीर विधियों को रनटाइम पर निर्धारित किया जाएगा ताकि फ्लाई पर सब कुछ गतिशील रूप से इकट्ठा किया जाना चाहिए। मैंने new Car("Ferrari", 2, "Red")
जैसी सरल वस्तुओं को बनाने के लिए अतीत में प्रतिबिंब का उपयोग किया है - मैं इसके साथ अच्छा हूं - लेकिन लैम्बडा अभिव्यक्तियों वाले पैरामीटर के साथ कभी भी कुछ भी नहीं - पैरामीटर के रूप में इन दो कारकों में वास्तव में मुझे अटक गया है। मैंने अभिव्यक्ति के पेड़ों में देखा है और मानते हैं कि यह गतिशील अभिव्यक्ति पैरामीटर बनाने के लिए समाधान का हिस्सा है, लेकिन आधार वस्तु और अतिरिक्त जंजीर विधियों को बनाने के लिए प्रतिबिंब के साथ एक साथ सिलाई करने के तरीके को पूरी तरह से अटकने की कोशिश कर रहा हूं।
धन्यवाद और समय देने के लिए मेरी समस्या पर और किसी भी मार्गदर्शन या जानकारी प्रदान करने में सक्षम हो सकता है देखने के लिए के लिए प्रशंसा
अग्रिम में।
अद्यतन: निष्कर्ष dasblinkenlight और उनके जवाब के लिए जॉन स्कीट को
बहुत धन्यवाद। मैंने dasblinkenlight के जवाब को चुना क्योंकि उसके कोड नमूने ने मुझे बंद कर दिया और तुरंत चल रहा था। विधि श्रृंखला के लिए मैंने मूल रूप से स्वीकार्य उत्तर में एक ही लूपिंग दृष्टिकोण का उपयोग किया है, इसलिए मैं उस कोड को दोहराना नहीं चाहूंगा लेकिन नीचे दिया गया कोड है जिसे मैंने गतिशील रूप से अभिव्यक्ति वृक्ष विधि कॉल को क्रिया प्रतिनिधियों में परिवर्तित करने के लिए लिखा था जिसे बाद में उल्लिखित Invoke()
के रूप में निष्पादित किया जा सकता था dasblinkenlight के जवाब में। यह, जैसा कि जॉन ने इंगित किया था वास्तव में समस्या का क्रूक्स था।
विधि मेटा डेटा स्टोर करने के लिए सहायक वर्ग।
public struct Argument
{
public string TypeName;
public object Value;
}
public class ExpressionTreeMethodCall
{
public string MethodName { get; set; }
public IList<Argument> Arguments { get; set; }
public ExpressionTreeMethodCall()
{
Arguments = new List<Argument>();
}
}
एक लैम्ब्डा अभिव्यक्ति विधि कॉल को इकट्ठा और फिर एक कार्रवाई प्रतिनिधि कहीं और निष्पादित किया जाना है (मेरे मामले में Invoke()
को तर्क के रूप में पारित कर दिया) के रूप में यह वापस जाने के लिए स्टेटिक विधि।
public static Action<T> ConvertExpressionTreeMethodToDelegate<T>(ExpressionTreeMethodCall methodData)
{
ParameterExpression type = Expression.Parameter(typeof(T));
var arguments = new List<ConstantExpression>();
var argumentTypes = new List<Type>();
foreach (var a in methodData.Arguments)
{
arguments.Add(Expression.Constant(a.Value));
argumentTypes.Add(Type.GetType(a.TypeName));
}
// Creating an expression for the method call and specifying its parameter.
MethodCallExpression methodCall = Expression.Call(type, typeof(T).GetMethod(methodData.MethodName, argumentTypes.ToArray()), arguments);
return Expression.Lambda<Action<T>>(methodCall, new[] { type }).Compile();
}
बहुत धन्यवाद दास .. तो अपने प्रदान की कोड का उपयोग कर - "makeRed" एक्शन वस्तु "chainedArgs" में संग्रहित किया जा सकता है और मार डाला "आह्वान()" के दौरान कॉल के दौरान चेनिंग पाश? – mmacneil007
@ mmacneil007 बिल्कुल, यह विचार है। 'एक्शन' एक प्रतिनिधि है जिसे अपने संबंधित विधि (आपके मामले में, 'अन्य प्रॉपर्टीज' 'के रूप में पारित करने के लिए, सरणी के' जंजीर आर्ट्स 'सरणी के अंदर एक सरणी में संग्रहीत किया जा सकता है। –
dasblinkenlight
बढ़िया, मुझे विश्वास है कि इसने मुझे सही रास्ते पर स्थापित किया है। अभी भी अभिव्यक्ति के पेड़ों के चारों ओर अपने सिर को लपेटना है, लेकिन मुझे लगता है कि आपके द्वारा यहां उल्लिखित दृष्टिकोण को चाल चलनी चाहिए। एक बार फिर धन्यवाद! – mmacneil007