दिलचस्प पोस्ट
मैं अपनी साइट के एपीआई उपयोगकर्ताओं को कैसे थ्रॉटल कर सकता हूं? एसक्यूएल – अप्रत्यक्ष विदेशी कुंजी शक्तियों का उपयोग कर एसक्यूएल फ़ाइल को कैसे निष्पादित करें? एक खाली JQuery ऑब्जेक्ट प्राप्त करना केवल पैरामीटरलेस कन्स्ट्रक्टर और प्रारंभकर्ता LINQ को इकाई में समर्थित हैं फ़ायरफ़ॉक्स में छिपे हुए स्क्रॉलबार (स्क्रॉल करने की अनुमति देता है लेकिन सिर्फ कोई स्क्रॉलबार नहीं) एंड्रॉइड में एक HTTP पोस्ट कैसे करें? जावा स्विंग: एक जार के भीतर से चित्र प्रदर्शित करना एक म्यूटक्स क्या है? परावर्तन के साथ स्थैतिक संपत्ति कैसे प्राप्त करें क्यों नहीं जावा संग्रह सामान्य तरीके निकालें? रिच टेक्स्ट बॉक्स को अपने प्रदर्शन को ताज़ा करने से कैसे रोकें? संस्था के प्रमुख अंतराल का क्या मतलब है, 1: 1 संस्था के ढांचे में संबंध py2exe – एकल निष्पादन योग्य फ़ाइल उत्पन्न गैर मानक स्थान में SSL समर्थन के साथ पायथन का निर्माण

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

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

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

  • प्रकार से मिलान करें (भेदभाव वाले यूनियनों के लिए पूर्ण कवरेज जांच के साथ) [नोट करें कि यह भी बाध्य चर के प्रकार का वर्णन करता है, सदस्य पहुंच इत्यादि देता है आदि)
  • विदग्ध द्वारा मैच
  • ऊपर के संयोजन (और संभवत: कुछ अन्य परिदृश्य जिन्हें मैं जानता हूं)

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

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 एक Func <वाहन, int> है

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

मेरे लिए, यह बराबर स्पष्ट है, अगर दो बार / या, या एक मिश्रित टर्नरी सशर्त (जो गैर-तुच्छ अभिव्यक्तियों के लिए बहुत गड़बड़ी होती है – ब्रैकेट्स गैलरी) दोहराया जाता है। यह बहुत सारे कास्टिंग से बचा जाता है, और अधिक विशिष्ट मिलानों के लिए सरल एक्सटेंशन (या तो सीधे या एक्स्टेंशन विधियों के माध्यम से) के लिए अनुमति देता है, उदाहरण के लिए, वीबी चयन के लिए तुलना में एक इनरेंज (…) मैच … केस "एक्स टू वाई "उपयोग

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

अतिरिक्त रूप से ध्यान दें कि मैं उपरोक्त तीन प्रकारों के साथ खेल रहा हूं:

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

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

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

Solutions Collecting From Web of "स्विच / पैटर्न मिलान विचार"

बार्ट डी स्मेट के उत्कृष्ट ब्लॉग में आप क्या वर्णन करते हैं, इसके बारे में 8 भाग श्रृंखलाएं हैं। यहां पहले भाग को ढूंढें

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

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

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

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

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

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

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

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

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

  • मोनो.रॉक खेल के मैदान में बहुत सी समान चीजें हैं (साथ ही गैर-कार्यात्मक-प्रोग्रामिंग-पर-उपयोगी अतिरिक्त)।
  • लुका बोलोगनीस के कार्यात्मक सी # पुस्तकालय
  • मैथ्यू पॉडवाइसोकी के कार्यात्मक सी # पर एमएसडीएन

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

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

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

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

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

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

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

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

 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 

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

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

 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)); } } 

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

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

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

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

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

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

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

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

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

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 ) ); 

यह नूगेट पर है और नेट 451 और नेटस्टैंडैंट 1 के लक्ष्य है