2009-09-16 3 views
14

क्या लैम्ब्डा अभिव्यक्ति में स्विच करना संभव है? अगर नहीं, क्यों? Resharper इसे एक त्रुटि के रूप में प्रदर्शित करते हैं।सी # लैम्ब्डा अभिव्यक्ति में स्विच

+7

क्या यह संकलित करता है? मैं Resharper का उपयोग वैध वाक्यविन्यास पर आपके अंतिम शब्द के रूप में नहीं करता। –

+0

निश्चित रूप से यह नहीं है और संकलित त्रुटि पुनर्विक्रेता प्रदर्शित आउटपुट के समान ही है: एक कथन बडी के साथ एक लैम्ब्डा अभिव्यक्ति अभिव्यक्ति वृक्ष को नहीं दी जा सकती है। – Toto

+0

एनबी: मुझे नहीं पता कि एक बयान शरीर क्या है। – Toto

उत्तर

21

आप एक बयान ब्लॉक लैम्ब्डा में कर सकते हैं:

Action<int> action = x => 
{ 
    switch(x) 
    { 
    case 0: Console.WriteLine("0"); break; 
    default: Console.WriteLine("Not 0"); break; 
    } 
}; 

लेकिन अगर आप एक "एकल अभिव्यक्ति लैम्ब्डा" में यह नहीं कर सकते, तो यह अमान्य है:

// This won't work 
Expression<Func<int, int>> action = x => 
    switch(x) 
    { 
    case 0: return 0; 
    default: return x + 1; 
    }; 

यह आपको इसका मतलब कर सकते हैं अभिव्यक्ति वृक्ष में स्विच का उपयोग न करें (कम से कम सी # कंपाइलर द्वारा उत्पन्न किया गया; मेरा मानना ​​है कि कम से कम .NET 4.0 पुस्तकालयों में इसके लिए समर्थन करता है)।

+0

हाँ वास्तव में समस्या यह है कि मैं एक अभिव्यक्ति वृक्ष चाहता हूं। यदि एक functino अगर एक els से बेहतर के आसपास कोई काम है? – Toto

+0

एक छोटा सुधार (हिंडसाइट पर ... हिंडसाइट कितना अच्छा है :-))। सी # 4.0 कंपाइलर अभी भी "जटिल" 'अभिव्यक्ति' ('if',' while' ...) के साथ नहीं बना सकता है, लेकिन आप उन्हें 'अभिव्यक्ति' वर्ग के उपयोग के माध्यम से बना सकते हैं। दो चीजें decoupled हैं।और कम हिंडसाइट के साथ: ओपी ने अभिव्यक्ति पेड़ों के बारे में पूछा। दूसरा 'एक्शन' एक अभिव्यक्ति > होना चाहिए था यह दिखाने के लिए कि आप वास्तव में एक अभिव्यक्ति वृक्ष चाहते थे, न कि एक प्रतिनिधि। – xanatos

+0

@xanatos: धन्यवाद, संपादित किया गया है। –

2

हम्म, मुझे कोई कारण नहीं दिखता कि यह क्यों काम नहीं करना चाहिए। बस

param => { 
    // Nearly any code! 
} 

delegate (param) { 
    // Nearly any code! 
} 

param => JustASingleExpression (No switches) 
5

हाँ, यह काम करता है, लेकिन आपको अपना कोड ब्लॉक में रखना होगा। उदाहरण:

private bool DoSomething(Func<string, bool> callback) 
{ 
    return callback("FOO"); 
} 

फिर, इसे कहते हैं:

DoSomething(val => 
       { 
        switch (val) 
        { 
         case "Foo": 
          return true; 

         default: 
          return false; 
        } 
       }); 
2

मैं भी :-)

[Test] 
public void SwitchInLambda() 
{ 
    TakeALambda(i => { 
     switch (i) 
     { 
      case 2: 
       return "Smurf"; 
      default: 
       return "Gnurf"; 
     } 
    }); 
} 

public void TakeALambda(Func<int, string> func) 
{ 
    System.Diagnostics.Debug.WriteLine(func(2)); 
} 

वर्क्स जाँच ठीक (आउटपुट "Smurf")!

+2

क्योंकि यह एक लैम्ब्डा अभिव्यक्ति नहीं है। एक ** लैम्ब्डा अभिव्यक्ति ** प्रकार 'अभिव्यक्ति > 'प्रकार का होगा। यह ** ** लैम्ब्डा फ़ंक्शन ** है। Takealambda के इनपुट पैरामीटर को चेंजिन करने का प्रयास करें और अंतर देखें। – xanatos

11

में एक शुद्ध Expression (.NET 3.5 में), निकटतम आप प्राप्त कर सकते हैं सशर्त एक यौगिक है:

Expression<Func<int, string>> func = x => 
     x == 1 ? "abc" : (
     x == 2 ? "def" : (
     x == 3 ? "ghi" : 
       "jkl")); /// yes, this is ugly as sin... 

मज़ा नहीं है, खासकर जब यह जटिल हो जाता है। आप एक बयान शरीर (केवल LINQ करने वाली वस्तुओं के साथ उपयोग के लिए) के साथ एक lamda अभिव्यक्ति मतलब है, तो कुछ भी ब्रेसिज़ के अंदर कानूनी है:

Func<int, string> func = x => { 
     switch (x){ 
      case 1: return "abc"; 
      case 2: return "def"; 
      case 3: return "ghi"; 
      default: return "jkl"; 
     } 
    }; 
बेशक

, आप काम आउटसोर्स करने के लिए सक्षम हो सकता है;

var qry = from cust in ctx.Customers 
      select new {cust.Name, CustomerType = ctx.MapType(cust.TypeFlag) }; 

जहां MapType है: उदाहरण के लिए - उदाहरण के लिए, LINQ करने वाली एसक्यूएल आप डेटा-प्रसंग पर एक पद्धति के लिए (डेटाबेस में) एक अदिश यूडीएफ (जो वास्तव में नहीं किया जाता है) को मैप करने के लिए अनुमति देता है एक यूडीएफ जो डीबी सर्वर पर काम करता है।

+1

आप अपने पहले कोड में कोष्ठक छोड़ सकते हैं - परिणाम * बहुत * कम बदसूरत है और मैं वास्तव में कभी-कभी इसका उपयोग करता हूं। माना जाता है कि यह थोड़ा सा उपयोग करने में लग रहा है लेकिन यह समकक्ष 'स्विच' ब्लॉक (कम से कम, मैं तर्क दूंगा) की तुलना में स्वाभाविक रूप से कम पठनीय नहीं है। –

+0

ब्रैकेट के बिना मैं कभी-कभी खो जाता हूं? /: आदि ... लेकिन हाँ, यह उनके बिना काम कर सकता है ;- –

+0

@MarcGravell क्या नेट 4.0 में शुद्ध 'अभिव्यक्ति' के लिए अभी भी कुछ बेहतर नहीं है? – ken2k

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

  • कोई संबंधित समस्या नहीं^_^