2017-05-07 10 views
5

मैं सरल गणित टोकनेज़र लिखता हूं और नई सी # pattern matching सुविधा का उपयोग करने का प्रयास करता हूं।पैटर्न मिलान केस

Tokenizer काफी सरल है:

public IEnumerable<IToken> Tokenize(string input) 
    { 
     const char decimalSeparator = '.'; 
     string inputWithoutSpaces = input.Replace(" ", string.Empty); 
     var numberBuffer = new StringBuilder(); 
     var letterBuffer = new StringBuilder(); 
     foreach (char c in inputWithoutSpaces) 
     { 
      switch (c) 
      { 
       case var _ when IsTerm(c, letterBuffer): 
        if (numberBuffer.Length > 0) 
        { 
         yield return EmptyNumberBufferAsLiteral(numberBuffer); 
         yield return new Operator('*'); 
        } 
        letterBuffer.Append(c); 
        break; 
       case decimalSeparator: 
       case var _ when IsDigit(c): 
        numberBuffer.Append(c); 
        break; 
       case var _ when IsOperator(c): 
        if (numberBuffer.Length > 0) 
        { 
         yield return EmptyNumberBufferAsLiteral(numberBuffer); 
        } 
        if (letterBuffer.Length > 0) 
        { 
         yield return EmptyLetterBufferAsTerm(letterBuffer); 
        } 
        yield return new Operator(c); 
        break; 
      } 
     } 
     if (numberBuffer.Length > 0) 
     { 
      yield return EmptyNumberBufferAsLiteral(numberBuffer); 
     } 
     if (letterBuffer.Length > 0) 
     { 
      yield return EmptyLetterBufferAsTerm(letterBuffer); 
     } 
    } 

मैं case var _ उपयोग कर रहा हूँ क्योंकि मैं if-else if श्रृंखला का उपयोग किए बिना शर्त से मिलान करना चाहते हैं, लेकिन मैं var variableName निर्दिष्ट किए बिना case when लिखने में असमर्थ हूँ।

क्या इस तरह के ऑपरेशन करने के लिए कोई शानदार तरीका है? या इन चीजों को करने का अनुशंसित तरीका है?

+1

ठीक है आप स्विच स्टेटमेंट्स में स्थिरांक का उपयोग करने की आवश्यकता के आसपास होने के लिए मिलान करने वाले पैटर्न का दुरुपयोग कर रहे हैं, इसलिए इसके आसपास जाने का कोई वास्तविक तरीका नहीं है। इसके अतिरिक्त, मुझे लगता है कि आपका तर्क शायद/बेहतर बयान के रूप में बेहतर/पढ़ता है। इसके विपरीत – DavidG

+1

@ डेविड जी, यह सक्रिय पैटर्न की तरह दिखता है, जो टोकननाइज़र और पार्सर्स के कार्यान्वयन को बहुत आसान बनाता है। सी # 7 में पैटर्न मिलान कई महत्वपूर्ण विशेषताओं को याद करता है। सक्रिय पैटर्न उनमें से एक है। मैं –

+0

@PanagiotisKanavos हां, हालांकि, मैं भाषा में अभी क्या उपलब्ध है के बारे में बात कर रहा हूं, लेकिन मैं पूरी तरह से मिलान करने के लिए उच्च प्राथमिकता प्राप्त करूंगा। मुझे पूरा यकीन है कि हम भविष्य में सी # में आने वाले बहुत अधिक पैटर्न मिलान सामग्री देखेंगे (धन्यवाद मुख्य रूप से एफ # मुझे लगता है) – DavidG

उत्तर

2

इस तरह के पैटर्न मिलान करने के लिए एक "फैंसी" तरीका है, जिसे सामान्य रूप से सक्रिय पैटर्न कहा जाता है। सी # हालांकि (अभी तक) सक्रिय पैटर्न का समर्थन नहीं करता है, लेकिन see this answer for an example of what they might look like if/when implemented

तो सक्रिय पैटर्न का उपयोग कर, अपने कोड की तरह कुछ के लिए देख खत्म होगा:

switch (c) 
{ 
    case Term(letterBuffer): 
     ... 
     break; 
    case decimalSeparator: 
    case Digit(): 
     ... 
     break; 
    case Operator(): 
     ... 
     break; 
} 

आप सी #, please upvote it on the csharplang github repo के भविष्य के संस्करण में इस सुविधा को देखने के लिए चाहते हैं।

इस बीच, आप if कथन के साथ चिपके हुए चयन के बीच सीमित हैं, जैसा कि अन्य ने कहा है, या जब आप गार्ड हैं तो इसका उपयोग कर रहे हैं। जो वास्तव में आप जाते हैं वह सिर्फ पसंदीदा शैली का मामला है।

+0

मैं "मिस्ड" मामलों को रोकने के लिए पहले लागू पूर्ण मिलान को देखना चाहता हूं। –

+1

@ पानागियोटिस कानावोस पूरी तरह से सहमत हैं। दुर्भाग्य से मुझे लगता है कि हम अन्य ओओ-संबंधित सुविधाओं के समूह के पक्ष में वापस धक्का देने के लिए उचित पैटर्न मिलान देखने जा रहे हैं। तो ओप के छद्म-सक्रिय पैटर्न कुछ समय के लिए करने का तरीका होगा। –

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