स्विच / पैटर्न मिलान विचार


151

मैं एफ # हाल ही में देख रहा हूं, और जब तक कि मैं जल्द ही किसी भी समय बाड़ को छलांग लगाने की संभावना नहीं रखता हूं, यह निश्चित रूप से कुछ क्षेत्रों को उजागर करता है जहां सी # (या पुस्तकालय समर्थन) जीवन को आसान बना सकता है।

विशेष रूप से, मैं एफ # की पैटर्न मिलान क्षमता के बारे में सोच रहा हूं, जो एक बहुत समृद्ध वाक्यविन्यास - वर्तमान स्विच / सशर्त सी # समकक्षों की तुलना में बहुत अधिक अभिव्यंजक अनुमति देता है। मैं एक प्रत्यक्ष उदाहरण देने की कोशिश नहीं करूँगा (मेरा F # इस पर निर्भर नहीं है), लेकिन संक्षेप में यह अनुमति देता है:

  • प्रकार से मेल करें (भेदभावपूर्ण यूनियनों के लिए पूर्ण-कवरेज की जाँच के साथ) [ध्यान दें कि यह बाध्य चर के लिए प्रकार को भी सीमित करता है, सदस्य को एक्सेस देने आदि]
  • विधेय द्वारा मिलान
  • उपरोक्त संयोजन (और संभवतः कुछ अन्य परिदृश्यों के बारे में मुझे जानकारी नहीं है)

हालांकि यह C # के लिए प्यारा होगा, अंततः [ahem] इस समृद्धि में से कुछ, अंतरिम में मैं देख रहा हूं कि रनटाइम पर क्या किया जा सकता है - उदाहरण के लिए, अनुमति देने के लिए कुछ वस्तुओं को एक साथ दस्तक देना काफी आसान है:

var getRentPrice = new Switch<Vehicle, int>()
        .Case<Motorcycle>(bike => 100 + bike.Cylinders * 10) // "bike" here is typed as Motorcycle
        .Case<Bicycle>(30) // returns a constant
        .Case<Car>(car => car.EngineType == EngineType.Diesel, car => 220 + car.Doors * 20)
        .Case<Car>(car => car.EngineType == EngineType.Gasoline, car => 200 + car.Doors * 20)
        .ElseThrow(); // or could use a Default(...) terminator

जहां getRentPrice एक फंक <वाहन, int> है।

[नोट - शायद स्विच / केस यहां गलत शब्द है ... लेकिन यह विचार दिखाता है]

मेरे लिए, यह / / या फिर एक समग्र टर्नरी सशर्त (जो गैर-तुच्छ अभिव्यक्तियों के लिए बहुत गन्दा हो जाता है - कोष्ठक की प्रचुरता) का उपयोग करके समतुल्य की तुलना में बहुत अधिक स्पष्ट है। यह बहुत अधिक कास्टिंग से बचा जाता है , और अधिक विशिष्ट मैचों के लिए सरल एक्सटेंशन (या तो सीधे या विस्तार विधियों के माध्यम से) की अनुमति देता है, उदाहरण के लिए एक इनरेंज (...) वीबी सिलेक्ट के लिए तुलनीय मैच ... केस "x to y “उपयोग।

मैं सिर्फ यह जानने की कोशिश कर रहा हूं कि क्या लोगों को लगता है कि उपर्युक्त (भाषा समर्थन के अभाव में) निर्माणों से बहुत लाभ है?

इसके अतिरिक्त ध्यान दें कि मैं ऊपर के 3 वेरिएंट्स के साथ खेल रहा हूं:

  • एक फंक <TSource, मूल्यांकन के लिए TValue> संस्करण - समग्र ternary सशर्त बयानों के लिए तुलनीय
  • एक क्रिया <TSource> संस्करण - अगर / वरना / if if / if if / else के बराबर है
  • एक अभिव्यक्ति <Func <TSource, TValue >> संस्करण - पहले के रूप में, लेकिन मनमाने ढंग से LINQ प्रदाताओं द्वारा प्रयोग करने योग्य

इसके अतिरिक्त, एक्सप्रेशन-आधारित संस्करण का उपयोग एक्सप्रेशन-ट्री री-राइटिंग को सक्षम करता है, अनिवार्य रूप से सभी शाखाओं को बार-बार मंगलाचरण का उपयोग करने के बजाय एक एकल संमिश्र सशर्त अभिव्यक्ति में सम्मिलित करता है। मैंने हाल ही में जाँच नहीं की है, लेकिन कुछ शुरुआती एंटिटी फ्रेमवर्क में मुझे लगता है कि मुझे यह आवश्यक लगता है, क्योंकि यह InvocationExpression को बहुत पसंद नहीं करता था। यह LINQ-to-Objects के साथ अधिक कुशल उपयोग की भी अनुमति देता है, क्योंकि यह बार-बार डेलीगेट इनवोकेशन से बचता है - परीक्षण उपरोक्त मैच की तरह दिखाते हैं (एक्सप्रेशन फॉर्म का उपयोग करके) समान गति से प्रदर्शन [मामूली रूप से तेज, वास्तव में] समतुल्य सी # की तुलना में समग्र सशर्त कथन। पूर्णता के लिए, फंक <...> आधारित-संस्करण को C # सशर्त कथन के रूप में 4 बार लिया गया, लेकिन अभी भी बहुत जल्दी है और अधिकांश उपयोग के मामलों में एक बड़ी अड़चन होने की संभावना नहीं है।

मैं उपरोक्त किसी भी विचार / इनपुट / समालोचना / आदि का स्वागत करता हूं (या समृद्ध सी # भाषा समर्थन की संभावनाओं पर - यहां उम्मीद है- पीपी)।


"मैं बस गेज करने की कोशिश कर रहा हूं अगर लोगों को लगता है कि उपरोक्त (भाषा समर्थन की अनुपस्थिति में) जैसे निर्माणों से बहुत लाभ है?" IMHO, हाँ। क्या पहले से मौजूद कुछ समान नहीं है? यदि नहीं, तो हल्के पुस्तकालय लिखने के लिए प्रोत्साहित महसूस करें।
कोनराड रुडोल्फ

10
आप VB .NET का उपयोग कर सकते हैं जो इसके चुनिंदा केस स्टेटमेंट में इसका समर्थन करता है। EEK!
जिम बर्गर

मैं अपने स्वयं के सींग को भी टटोलूंगा और अपनी लाइब्रेरी में एक लिंक जोड़ूंगा
एलेक्सी रोमानोव

1
मुझे यह विचार पसंद है और यह स्विच-केस के बहुत अच्छे और अधिक लचीले रूप के लिए बनाता है; हालांकि, यह वास्तव में एक अगर-तब आवरण के रूप में Linq की तरह सिंटैक्स का उपयोग करने का एक अलंकृत तरीका नहीं है? मैं किसी को वास्तविक सौदे के स्थान पर इसका उपयोग करने से हतोत्साहित करूंगा, अर्थात एक switch-caseबयान। मुझे गलत मत समझो, मुझे लगता है कि इसकी जगह है और मैं शायद इसे लागू करने के लिए रास्ता तलाशूंगा।
आईएब्रिज

2
हालांकि यह सवाल दो साल से अधिक पुराना है, लेकिन यह उल्लेख करना उचित है कि सी # 7 जल्द ही (ईश) मिलान क्षमताओं के साथ बाहर आ रहा है।
अबियान ४।

जवाबों:


22

मुझे पता है कि यह एक पुराना विषय है, लेकिन c # 7 में आप यह कर सकते हैं:

switch(shape)
{
    case Circle c:
        WriteLine($"circle with radius {c.Radius}");
        break;
    case Rectangle s when (s.Length == s.Height):
        WriteLine($"{s.Length} x {s.Height} square");
        break;
    case Rectangle r:
        WriteLine($"{r.Length} x {r.Height} rectangle");
        break;
    default:
        WriteLine("<unknown shape>");
        break;
    case null:
        throw new ArgumentNullException(nameof(shape));
}

सी # और एफ # के बीच यहां उल्लेखनीय अंतर पैटर्न मैच की पूर्णता है। यह पैटर्न मिलान उपलब्ध हर संभव मामले को कवर करता है, पूरी तरह से वर्णित है, यदि आप नहीं करते हैं तो संकलक से चेतावनी। हालांकि आप सही तरीके से तर्क दे सकते हैं कि डिफ़ॉल्ट केस ऐसा करता है, यह अक्सर एक रन-टाइम अपवाद का अभ्यास करता है।
वोरोनोयपोटो 10

37

सी # में ऐसी "कार्यात्मक" चीजें करने की कोशिश करने के बाद (और यहां तक ​​कि उस पर एक किताब का प्रयास भी), मैं इस निष्कर्ष पर पहुंचा हूं कि नहीं, कुछ अपवादों के साथ, ऐसी चीजें बहुत ज्यादा मदद नहीं करती हैं।

मुख्य कारण यह है कि एफ # जैसी भाषाओं को इन सुविधाओं का सही समर्थन करने से अपनी शक्ति प्राप्त होती है। "आप इसे कर सकते हैं" नहीं, लेकिन "यह सरल है, यह स्पष्ट है, यह अपेक्षित है"।

उदाहरण के लिए, पैटर्न मिलान में, आपको कंपाइलर बताता है कि क्या कोई अधूरा मैच है या जब दूसरा मैच कभी हिट नहीं होगा। यह खुले अंत प्रकारों के साथ कम उपयोगी है, लेकिन जब एक भेदभाव संघ या ट्यूपल्स से मेल खाता है, तो यह बहुत ही कम है। F # में, आप लोगों से मैच का पैटर्न बनाने की अपेक्षा करते हैं, और यह तुरंत समझ में आता है।

"समस्या" यह है कि एक बार जब आप कुछ कार्यात्मक अवधारणाओं का उपयोग करना शुरू करते हैं, तो इसे जारी रखना चाहते हैं। हालांकि, सी # में tuples, काम करता है, आंशिक विधि आवेदन और currying, पैटर्न मिलान, नेस्टेड काम करता है, जेनरिक, इकाई सहायता आदि का लाभ हो जाता है बहुत बहुत जल्दी बदसूरत,। यह मजेदार है, और कुछ बहुत ही स्मार्ट लोगों ने C # में कुछ बहुत ही शांत चीजें की हैं, लेकिन वास्तव में इसका उपयोग करना भारी लगता है।

C # में (अक्सर-प्रोजेक्ट्स) का उपयोग करके मैंने क्या समाप्त किया है:

  • अनुक्रम कार्यों, IEnumerable के लिए विस्तार के तरीकों के माध्यम से। ForEach या Process ("लागू करें" जैसी चीजें? - सीक्वेंस आइटम पर एक एक्शन करते हैं क्योंकि यह एनुमरेटेड है) फिट है क्योंकि C # सिंटैक्स इसे अच्छी तरह से सपोर्ट करता है।
  • सामान्य कथन पैटर्न का सार। जटिल प्रयास / पकड़ / अंत में ब्लॉक या अन्य शामिल (अक्सर भारी सामान्य) कोड ब्लॉक। यहाँ भी LINQ-to-SQL फैली हुई है।
  • टुपल्स, कुछ हद तक।

** लेकिन ध्यान दें: स्वचालित सामान्यीकरण और प्रकार की कमी की कमी वास्तव में इन सुविधाओं के उपयोग में बाधा है। **

यह सब कहा, जैसा कि किसी और ने उल्लेख किया है, एक छोटी सी टीम पर, एक विशिष्ट उद्देश्य के लिए, हां, शायद वे मदद कर सकते हैं यदि आप सी # के साथ फंस गए हैं। लेकिन मेरे अनुभव में, वे आमतौर पर अधिक परेशानी की तरह महसूस करते थे जितना कि वे लायक थे - वाईएमएमवी।

कुछ अन्य लिंक:


25

तर्क का कारण यह है कि C # को टाइप पर स्विच करना आसान नहीं है क्योंकि यह मुख्य रूप से एक ऑब्जेक्ट-ओरिएंटेड भाषा है, और ऑब्जेक्ट-ओरिएंटेड शब्दों में ऐसा करने का 'सही' तरीका है वाहन पर GetRentPrice पद्धति को परिभाषित करना और इसे व्युत्पन्न वर्गों में ओवरराइड करें।

उस ने कहा, मैंने एफ # और हास्केल जैसी बहु-प्रतिमान और कार्यात्मक भाषाओं के साथ खेलने में थोड़ा समय बिताया है, जिसमें इस प्रकार की क्षमता है, और मैं कई स्थानों पर आया हूं, जहां यह पहले उपयोगी होगा (जैसे जब आप। उन प्रकारों को नहीं लिख रहे हैं जिन्हें आपको स्विच करने की आवश्यकता है ताकि आप उन पर एक आभासी पद्धति को लागू न कर सकें) और यह कुछ ऐसा है जिसका मैं भाषा में भेदभाव वाली यूनियनों के साथ स्वागत करूंगा।

[संपादित करें: प्रदर्शन के बारे में हटाए गए भाग के रूप में मार्क ने संकेत दिया कि यह कम-चक्कर हो सकता है]

एक और संभावित समस्या एक प्रयोज्य है - यह अंतिम कॉल से स्पष्ट है कि क्या होता है यदि मैच किसी भी स्थिति को पूरा करने में विफल रहता है, लेकिन दो या अधिक स्थितियों से मेल खाने पर व्यवहार क्या है? क्या इसे अपवाद फेंकना चाहिए? क्या यह पहला या आखिरी मैच लौटना चाहिए?

इस तरह की समस्या को हल करने के लिए मैं जिस तरह का उपयोग करता हूं, वह है कि मूल्य के रूप में कुंजी और लंबो के रूप में एक शब्दकोश फ़ील्ड का उपयोग करें, जो कि ऑब्जेक्ट इनिशियल सिंटैक्स का उपयोग करके निर्माण करने के लिए बहुत अनुकूल है; हालाँकि, यह केवल ठोस प्रकार के लिए खाता है और अतिरिक्त विधेय की अनुमति नहीं देता है, इसलिए यह अधिक जटिल मामलों के लिए उपयुक्त नहीं हो सकता है। [साइड नोट - यदि आप C # कंपाइलर के आउटपुट को देखते हैं तो यह अक्सर स्विच स्टेटमेंट को डिक्शनरी-आधारित जंप टेबल में बदल देता है, इसलिए यह एक अच्छा कारण प्रतीत नहीं होता है क्योंकि यह टाइप पर स्विच करने का समर्थन नहीं कर सकता]


1
वास्तव में - मेरे पास जो संस्करण है वह प्रतिनिधि और अभिव्यक्ति दोनों संस्करणों में शॉर्ट सर्किट करता है। अभिव्यक्ति संस्करण एक कंपाउंड सशर्त के लिए संकलित है; प्रतिनिधि संस्करण केवल विधेय और क्रिया / क्रियाओं का एक सेट है - एक बार जब यह एक मैच होता है तो यह रुक जाता है।
मार्क ग्रेवल

रुचिकर - एक सरसरी नज़र से मैंने मान लिया कि इसे प्रत्येक स्थिति की कम से कम बुनियादी जाँच करनी होगी क्योंकि यह एक विधि श्रृंखला की तरह दिखती थी, लेकिन अब मुझे एहसास हुआ कि वास्तव में इसे बनाने के लिए एक वस्तु उदाहरण का पीछा कर रहे हैं ताकि आप ऐसा कर सकें। मैं उस कथन को हटाने के लिए अपना उत्तर संपादित करूँगा।
ग्रेग बीच

22

मुझे नहीं लगता कि इन प्रकार की पुस्तकालयों (जो भाषा एक्सटेंशन की तरह काम करती हैं) को व्यापक स्वीकृति प्राप्त होने की संभावना है, लेकिन वे साथ खेलने में मज़ेदार हैं, और विशिष्ट डोमेन में काम करने वाली छोटी टीमों के लिए वास्तव में उपयोगी हो सकते हैं जहां यह उपयोगी है। उदाहरण के लिए, यदि आप 'व्यापार नियम / तर्क' के टन लिख रहे हैं जो इस तरह के और इस तरह के मनमाने ढंग से परीक्षण करता है, तो मैं देख सकता हूं कि यह कैसे उपयोगी होगा।

मुझे कोई सुराग नहीं है अगर यह कभी भी सी # भाषा की विशेषता होने की संभावना है (संदिग्ध लगता है, लेकिन भविष्य को कौन देख सकता है)?

संदर्भ के लिए, संबंधित F # लगभग है:

let getRentPrice (v : Vehicle) = 
    match v with
    | :? Motorcycle as bike -> 100 + bike.Cylinders * 10
    | :? Bicycle -> 30
    | :? Car as car when car.EngineType = Diesel -> 220 + car.Doors * 20
    | :? Car as car when car.EngineType = Gasoline -> 200 + car.Doors * 20
    | _ -> failwith "blah"

यह मानते हुए कि आप एक वर्ग पदानुक्रम को परिभाषित करेंगे

type Vehicle() = class end

type Motorcycle(cyl : int) = 
    inherit Vehicle()
    member this.Cylinders = cyl

type Bicycle() = inherit Vehicle()

type EngineType = Diesel | Gasoline

type Car(engType : EngineType, doors : int) = 
    inherit Vehicle()
    member this.EngineType = engType
    member this.Doors = doors

2
एफ # संस्करण के लिए धन्यवाद। मुझे लगता है मैं की तरह जिस तरह से एफ # हैंडल इस लगता है, लेकिन मुझे यकीन है कि (कुल) एफ # समय पर सही विकल्प है नहीं कर रहा हूँ तो मुझे लगता है कि बीच मैदान ... चलने के लिए हो रही है
मार्क Gravell

13

आपके प्रश्न का उत्तर देने के लिए, हाँ, मुझे लगता है कि वाक्यविन्यास निर्माण से मेल खाते पैटर्न उपयोगी हैं। मैं इसके लिए C # में सिंथैटिक सपोर्ट देखना चाहूंगा।

यहाँ मेरा एक वर्ग का कार्यान्वयन है जो आपके वर्णन के अनुसार एक ही वाक्य रचना प्रदान करता है (लगभग)

public class PatternMatcher<Output>
{
    List<Tuple<Predicate<Object>, Func<Object, Output>>> cases = new List<Tuple<Predicate<object>,Func<object,Output>>>();

    public PatternMatcher() { }        

    public PatternMatcher<Output> Case(Predicate<Object> condition, Func<Object, Output> function)
    {
        cases.Add(new Tuple<Predicate<Object>, Func<Object, Output>>(condition, function));
        return this;
    }

    public PatternMatcher<Output> Case<T>(Predicate<T> condition, Func<T, Output> function)
    {
        return Case(
            o => o is T && condition((T)o), 
            o => function((T)o));
    }

    public PatternMatcher<Output> Case<T>(Func<T, Output> function)
    {
        return Case(
            o => o is T, 
            o => function((T)o));
    }

    public PatternMatcher<Output> Case<T>(Predicate<T> condition, Output o)
    {
        return Case(condition, x => o);
    }

    public PatternMatcher<Output> Case<T>(Output o)
    {
        return Case<T>(x => o);
    }

    public PatternMatcher<Output> Default(Func<Object, Output> function)
    {
        return Case(o => true, function);
    }

    public PatternMatcher<Output> Default(Output o)
    {
        return Default(x => o);
    }

    public Output Match(Object o)
    {
        foreach (var tuple in cases)
            if (tuple.Item1(o))
                return tuple.Item2(o);
        throw new Exception("Failed to match");
    }
}

यहाँ कुछ परीक्षण कोड है:

    public enum EngineType
    {
        Diesel,
        Gasoline
    }

    public class Bicycle
    {
        public int Cylinders;
    }

    public class Car
    {
        public EngineType EngineType;
        public int Doors;
    }

    public class MotorCycle
    {
        public int Cylinders;
    }

    public void Run()
    {
        var getRentPrice = new PatternMatcher<int>()
            .Case<MotorCycle>(bike => 100 + bike.Cylinders * 10) 
            .Case<Bicycle>(30) 
            .Case<Car>(car => car.EngineType == EngineType.Diesel, car => 220 + car.Doors * 20)
            .Case<Car>(car => car.EngineType == EngineType.Gasoline, car => 200 + car.Doors * 20)
            .Default(0);

        var vehicles = new object[] {
            new Car { EngineType = EngineType.Diesel, Doors = 2 },
            new Car { EngineType = EngineType.Diesel, Doors = 4 },
            new Car { EngineType = EngineType.Gasoline, Doors = 3 },
            new Car { EngineType = EngineType.Gasoline, Doors = 5 },
            new Bicycle(),
            new MotorCycle { Cylinders = 2 },
            new MotorCycle { Cylinders = 3 },
        };

        foreach (var v in vehicles)
        {
            Console.WriteLine("Vehicle of type {0} costs {1} to rent", v.GetType(), getRentPrice.Match(v));
        }
    }

9

पैटर्न मिलान (जैसा कि यहां बताया गया है ), इसका उद्देश्य उनके प्रकार विनिर्देश के अनुसार मूल्यों का पुनर्निर्माण करना है। हालाँकि, C # में एक वर्ग (या प्रकार) की अवधारणा आपके साथ सहमत नहीं है।

बहु-प्रतिमान भाषा डिजाइन के साथ गलत नहीं है, इसके विपरीत, सी # में लैम्ब्डा होना बहुत अच्छा है, और हास्केल ईओओ के लिए जरूरी सामान कर सकता है। लेकिन यह बहुत सुरुचिपूर्ण समाधान नहीं है, हास्केल फैशन में नहीं।

लेकिन चूंकि अनुक्रमिक प्रक्रियात्मक प्रोग्रामिंग भाषाओं को लैम्ब्डा कैलकुलस के संदर्भ में समझा जा सकता है, और सी # एक अनुक्रमिक प्रक्रियात्मक भाषा के मापदंडों के भीतर अच्छी तरह से फिट होने के लिए होता है, यह एक अच्छा फिट है। लेकिन, हास्केल के शुद्ध कार्यात्मक संदर्भ से कुछ लेना, और फिर उस विशेषता को एक ऐसी भाषा में डालना जो शुद्ध नहीं है, ठीक है, बस ऐसा करने से बेहतर परिणाम की गारंटी नहीं होगी।

मेरा कहना यह है कि, जो पैटर्न मिलान टिक बनाता है वह भाषा के डिजाइन और डेटा मॉडल से जुड़ा होता है। ऐसा कहने के बाद, मुझे विश्वास नहीं है कि पैटर्न मिलान C # की एक उपयोगी विशेषता है क्योंकि यह विशिष्ट C # समस्याओं को हल नहीं करता है और न ही यह अनिवार्य प्रोग्रामिंग प्रतिमान के भीतर अच्छी तरह से फिट बैठता है।


1
शायद। वास्तव में, मैं यह समझाने के लिए "हत्यारे" तर्क पर विचार करने के लिए संघर्ष करूंगा कि इसकी आवश्यकता क्यों होगी (भाषा को और अधिक जटिल बनाने की कीमत पर "शायद कुछ किनारे के मामलों में अच्छा" के विपरीत)।
मार्क Gravell

5

ऐसी चीजों को करने का ओएचओ तरीका विज़िटर पैटर्न है। आपके आगंतुक सदस्य तरीके बस मामले के निर्माण के रूप में कार्य करते हैं और आप भाषा को प्रकारों में "झांकने" के बिना उपयुक्त प्रेषण को संभालने देते हैं।


4

यद्यपि यह टाइप पर स्विच करने के लिए बहुत 'सी-शार्प' नहीं है, मुझे पता है कि निर्माण सामान्य उपयोग में काफी मददगार होगा - मेरे पास कम से कम एक व्यक्तिगत परियोजना है जो इसका उपयोग कर सकती है (हालांकि इसके प्रबंधनीय एटीएम)। क्या अभिव्यक्ति के पेड़ को फिर से लिखने के साथ एक संकलन प्रदर्शन समस्या है?


यदि आप फिर से उपयोग के लिए वस्तु को कैश नहीं करते हैं (जो मोटे तौर पर सी # लैम्ब्डा अभिव्यक्ति कैसे काम करता है, सिवाय संकलक कोड छुपाता है)। फिर से लिखना निश्चित रूप से संकलित प्रदर्शन में सुधार करता है - हालांकि, नियमित उपयोग के लिए (LINQ-to-something के बजाय) मुझे उम्मीद है कि प्रतिनिधि संस्करण अधिक उपयोगी हो सकता है।
मार्क Gravell

नोट भी - यह जरूरी नहीं है कि यह एक प्रकार पर स्विच हो - यह एक समग्र सशर्त के रूप में भी इस्तेमाल किया जा सकता है (यहां तक ​​कि LINQ के रूप में) - लेकिन बिना गड़बड़ x => टेस्ट के? Result1: (? Test2 Result2: (test3 परिणाम 3: Result4))
मार्क Gravell

यह जानकर अच्छा लगा, हालाँकि मैं वास्तविक संकलन का प्रदर्शन था : csc.exe कितना समय लेता है - मैं C # से परिचित नहीं हूँ यह जानने के लिए कि क्या वास्तव में कोई समस्या है, लेकिन यह C ++ के लिए एक बड़ा मुद्दा है।
साइमन बुकान

सीएससी इस पर ब्लिंक करेगा नहीं है - यह तो कैसे LINQ काम करता है के समान है, और सी # 3.0 संकलक LINQ / विस्तार के तरीकों आदि पर काफी अच्छा है
मार्क Gravell

3

मुझे लगता है कि यह वास्तव में दिलचस्प (+1) लगता है, लेकिन सावधान रहने की एक बात: सी # कंपाइलर स्विच स्टेटमेंट को अनुकूलित करने में बहुत अच्छा है। सिर्फ शॉर्ट सर्कुलेटिंग के लिए नहीं - आपके पास कितने मामले और इतने पर निर्भर करता है कि आप पूरी तरह से अलग आईएल प्राप्त करते हैं।

आपका विशिष्ट उदाहरण कुछ ऐसा करता है जो मुझे बहुत उपयोगी लगता है - प्रकार से मामले के बराबर कोई सिंटैक्स नहीं है, जैसे (उदाहरण के लिए) typeof(Motorcycle)एक स्थिर नहीं है।

यह गतिशील अनुप्रयोग में अधिक दिलचस्प हो जाता है - यहाँ आपका तर्क आसानी से डेटा-चालित हो सकता है, जिससे 'नियम-इंजन' शैली का निष्पादन हो सकता है।


0

OneOf नामक एक लाइब्रेरी का उपयोग करके आप प्राप्त कर सकते हैं

से अधिक प्रमुख लाभ switch(और ifऔर exceptions as control flowवहाँ कोई डिफ़ॉल्ट हैंडलर है या के माध्यम से गिर -) है कि यह संकलन समय सुरक्षित है

   OneOf<Motorcycle, Bicycle, Car> vehicle = ... //assign from one of those types
   var getRentPrice = vehicle
        .Match(
            bike => 100 + bike.Cylinders * 10, // "bike" here is typed as Motorcycle
            bike => 30, // returns a constant
            car => car.EngineType.Match(
                diesel => 220 + car.Doors * 20
                petrol => 200 + car.Doors * 20
            )
        );

यह Nuget पर है और net451 और netstandard1.6 को लक्षित करता है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.