2012-09-07 24 views
10

मैं out पैरामीटर के साथ एक लैम्ब्डा अभिव्यक्ति को परिभाषित करना चाहता हूं। क्या यह करना संभव है?क्या पैरामीटर एक्स्प्रेशन को बाहर करना संभव है?

नीचे एक सी # .Net 4.0 कंसोल ऐप से कोड स्निपेट हैं जो मैंने कोशिश की थी।

:

आप Procedure25 में देख सकते हैं मैं एक प्रतिनिधि एक आउटपुट पैरामीटर है कि हालांकि, परिभाषित करने के लिए लैम्ब्डा भाव का उपयोग कर सकते, जब मैं LINQ एक्सप्रेशन का उपयोग करना भी ऐसा ही करना चाहते हैं, प्रक्रिया 24 में कोड के साथ विफल

System.ArgumentException बिना क्रिया संदेश = ParameterExpression 'System.Boolean' प्रकार की प्रकार के प्रतिनिधि पैरामीटर के लिए नहीं किया जा सकता था स्रोत = System.Core

'& System.Boolean' मैं मैं इस्तेमाल कर सकते हैं पता है एक इनपुट कक्षा obj एक बूल सदस्य के साथ ect और कॉलर को उस तरह के मूल्य को वापस पास करें, लेकिन अगर मैं किसी भी तरह से पैरामीटर को परिभाषित कर सकता हूं तो मैं उत्सुक था।

धन्यवाद

static void Main(string[] args) 
{ 
    Procedure25(); 
    Procedure24(); 
    Console.WriteLine("Done!"); 
    Console.ReadKey(); 
} 

private delegate int Evaluate(string value, out bool usesVars); 

private static void Procedure24() 
{ 

    // This fails to compile: 
    //Expression<Evaluate> x = (string val, out bool usesSimVals) => 
    //{ 
    // usesSimVals = true; 
    // Console.WriteLine(val); 
    // return 1; 
    //}; 


    ParameterExpression valueParameter = Expression.Parameter(typeof (string)); 
    MethodCallExpression methodCall = Expression.Call(typeof(Console).GetMethod("WriteLine", new Type[] { typeof(object) }), valueParameter); 

    bool usesVars; 
    ParameterExpression usesVarsParameter = Expression.Parameter(typeof (bool), "out usesVars"); 


    Expression.Lambda<Evaluate>(methodCall, valueParameter, usesVarsParameter).Compile()("test", out usesVars); 
    Console.WriteLine(usesVars); 

} 

private static void Procedure25() 
{ 
    Evaluate x = (string value, out bool vars) => { vars = true; 
    Console.WriteLine(value); 
                return 1; 
    }; 

    bool usesVars; 
    x("test", out usesVars); 
} 

संपादित करें:

Ani, भयानक, धन्यवाद। तो मुख्य बात यह है कि पैरामीटर प्रकार पर MakeByRefType को कॉल करना था।

private static void Procedure24() 
{ 
    ParameterExpression valueParameter = Expression.Parameter(typeof (string)); 
    MethodCallExpression methodCall = Expression.Call(typeof(Console).GetMethod("WriteLine", new Type[] { typeof(object) }), valueParameter); 

    bool usesVars; 
    ParameterExpression usesVarsParameter = Expression.Parameter(typeof (bool).MakeByRefType(), "out usesVars"); 

    Expression block = Expression.Block(methodCall, Expression.Assign(usesVarsParameter, Expression.Constant(true)), Expression.Constant(1)); 
    int result = Expression.Lambda<Evaluate>(block, valueParameter, usesVarsParameter).Compile()("test", out usesVars); 
    Console.WriteLine("Result={0}, usesVars={1}", result, usesVars); 

} 

उत्तर

7

आप Type.MakeByRefType की जरूरत: जो आपके कोड नमूना एक अतिरिक्त समस्या है

var usesVarsParameter = Expression.Parameter(typeof(bool).MakeByRefType(), "usesVars"); 

नोट:

रिकॉर्ड यहां के लिए एक कोड का टुकड़ा है कि Ani की सुझाव के आधार पर काम करता है है अपने expression- शरीर सही नहीं है - यह एक मूल्य वापस नहीं कर रहा है जब इसे प्रतिनिधि-प्रकार के रिटर्न-प्रकार को पूरा करने के लिए int लौटाया जाना चाहिए।

var body = Expression.Block(methodCall, Expression.Constant(1)); 

Expression.Lambda<Evaluate>(body, valueParameter, usesVarsParameter) 
      .Compile()("test", out usesVars); 

भी ध्यान रखें कि आप अभिव्यक्ति के अंदर out पैरामीटर बताए नहीं हैं:

यहाँ एक तरह से आप तय कर सकते हैं कि (अपने लैम्ब्डा उदाहरण की तरह) है। Expression.Lambda आपको इससे दूर जाने की इजाजत दे रहा है, जिसकी मुझे उम्मीद नहीं थी, लेकिन हे, बीसीएल को सी # के समान नियमों का पालन नहीं करना पड़ेगा!

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