गैर-सहज ज्ञान युक्त सी # स्ट्रिंग के बाद कारण। () कार्यान्वयन


10

C # में अगर मुझे एक stringदूसरे से अलग होना है तो मुझे stringऐसा कुछ करना होगा:

testString.Split(new string[] { "anotherString" }, StringSplitOptions.None);

अतिभारित String.SplitMSDN दस्तावेज़ीकरण से हम कार्यान्वयन देख सकते हैं और इस तरह की कॉल क्यों करनी पड़ती है।

पायथन से आ रहा है , मेरे लिए यह समझना मुश्किल है कि इस तरह की कॉल की आवश्यकता क्यों है। मेरा मतलब है कि मैं Regex.Splitअजगर के कार्यान्वयन की तुलना में एक समान वाक्यविन्यास प्राप्त करने के लिए उपयोग कर सकता हूं, लेकिन मुझे कुछ सरल के लिए कम प्रदर्शन (सेटअप समय) की कीमत पर करना होगा ।

तो मूल रूप से, मेरा सवाल यह है कि आखिर हम ऐसा क्यों नहीं कर सकते:

testString.Split("anotherString");

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


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

@ कैलेथ आप इस बारे में विस्तार से बता सकते हैं। शायद मैं गलत हूं, लेकिन मुझे नहीं लगता कि इसके बारे में क्या अच्छा है। मैं क्यों नहीं कर सकता testString.Split(",.;");और testString.Split(new Char [] {',', '.', ';',);जो एक ही बात नहीं है।
स्क्रेच

@ यूफोरिक मैंने भी बहुत संघर्ष किया, लेकिन यह इतना अजीब होगा। आशा है कि कोई और अधिक तर्क जवाब के साथ आता है।
स्क्रेच

यदि IEnumerable<char>आप सुझाव दे रहे हैं कि आप कुछ अतिरिक्त मामलों में अस्पष्ट दिखाई दे सकते हैं, तो क्या आप एक स्ट्रिंग पर टाइप कर सकते हैं?
जॉन वू

@ जॉनव्हू शायद यह एक व्यक्तिगत बात है, लेकिन 99.9% वाक्यविन्यास की घटनाओं के लिए testString.Split("anotherString");, मुझे यह कहने के लिए पूरा विश्वास है कि अपेक्षित व्यवहार पूरे स्ट्रिंग पर ( anotherStringइस मामले में) परिसीमन करना था ।
12

जवाबों:


15

कभी-कभी एक से अधिक चार / स्ट्रिंग पर विभाजन करना उपयोगी होता है, इसलिए एपीआई आपको एक सरणी प्रदान करने की अनुमति देता है, जिससे आपको अधिकतम लचीलापन मिलता है। charS के मामले में , आपको सिंटैक्स और लचीलेपन दोनों की सरलता मिलती है क्योंकि पैरामीटर को चिह्नित किया जाता है paramsताकि आप इसके Split('x')बजाय लिख सकें Split(new[]{'x'})

तो तार के लिए एक समान विकल्प क्यों नहीं है, जो आपको लिखने की अनुमति देता है Split("x")?

यह शायद एपीआई कैसे डिजाइन किया गया है का एक दुर्भाग्यपूर्ण परिणाम है। शुरू में यह केवल वर्णों पर विभाजन की अनुमति देता था। स्ट्रिंग्स पर विभाजन 2.0 में जोड़ा गया था, शायद इसलिए इसे लागू करना अधिक जटिल है। लेकिन इसे जोड़ना String.Split(string)या String.Split(string[])ओवरलोड करना संभव नहीं था , क्योंकि यह अभिव्यक्ति को testString.Split(null)अस्पष्ट बना देगा और यह कोड अब संकलित नहीं करेगा।

testString.Split(null) यह वास्तव में एक सुंदर आम मुहावरा है क्योंकि यह व्हाट्सएप पर स्ट्रिंग को विभाजित करता है, इसलिए इस तरह के टूटना स्वीकार्य होने के लिए बहुत व्यापक होगा।

nullविशेष व्यवहार के लिए एक स्विच के रूप में -पैरमेट का उपयोग करना आमतौर पर इन दिनों खराब डिजाइन माना जाता है, इसलिए मुझे लगता है कि यह कहना उचित है कि यह एपीआई केवल त्रुटिपूर्ण है।

कोई कारण नहीं है Split(string[], Int32), शायद एक समान कारण के लिए - यह Split(char[], Int32)पहले पैरामीटर है अगर यह अस्पष्ट होगा null। वहाँ रहे हैं के साथ इसी तरह भार के StringSplitOptionsमानकों, लेकिन इन सब, 2.0 में एक ही समय में जोड़ा गया था ताकि कोई अस्पष्टता नहीं मौजूदा कोड में पेश किया गया था।

ध्यान दें

स्पष्ट होने के लिए, यह सिर्फ मेरी परिकल्पना है, मुझे .net फ्रेमवर्क डिजाइनरों द्वारा वास्तविक सोच का पता नहीं है।


1
ठीक है, यह सब उपयोगी है? संदेह है कि। और यह केवल एक एपीआई-ब्रेक है, एबीआई एक नहीं।
डेडुप्लिकेटर

2
@ डेडप्लिकेटर: स्प्लिट (नल) व्हाट्सएप पर विभाजित होता है, इसलिए यह विभाजन के लिए संभवतः सबसे आम उपयोग के मामलों में से एक है, भले ही यह इस तरह एक नल का उपयोग करने के लिए खराब एपीआई डिजाइन है।
जैक्सबी

1
मुझे लगता है कि @Deduplicator कहना चाहता था कि Split(null)अगर आप अनुमति दें तो बेकार है Split("")। इस तथ्य के अलावा कि यह एक तरह से बेहतर सिंटैक्स की अनुमति देगा, उत्तरार्द्ध वैसे भी अधिक
क्रिया है

1
@scharette: ज़रूर, लेकिन पिछड़ी अनुकूलता को तोड़े बिना अब इसे बदलना संभव नहीं है।
जैक्सबी

1
एक नोट: वर्तमान C # 8 पूर्वावलोकन के साथ, आधार प्रकारों को बंद करने से अशक्तता String.Split(null)अब अस्पष्ट नहीं होगी, इसलिए वे अधिभार जोड़ सकते हैं
BgrWorker

2

विधियों के लेखक नहीं होने के कारण, मुझे नहीं पता कि ओवरलोड का वह सेट क्यों चुना गया था। हालांकि, यहां दो बातें ध्यान देने योग्य हैं:

  1. यदि आप किसी एकल वर्ण पर विभाजन कर रहे हैं, तो public string[] Split(params char[] separator) संस्करण का उपयोग इस प्रकार किया जा सकता है:

    var splitValues = testString.Split(',');

    जैसा कि char[]एक paramsपैरामीटर है।

  2. आप जो चाहते हैं उसे प्राप्त करने के लिए आसानी से अपनी खुद की एक्सटेंशन विधि यहाँ जोड़ सकते हैं:

    public static class StringExtensions
    {
        public static string[] Split(this string source, string separator)
            => source.Split(new string[] { separator }, StringSplitOptions.None);
    }
    

    और अब testString.Split("anotherString");आपके लिए काम करेगा।


1
प्रतिक्रिया के लिए धन्यवाद। यद्यपि आपका उत्तर सहायक और संक्षिप्त है, मैं आपसे सहमत नहीं हो सकता। खासतौर पर दूसरा बिंदु। एक और कारण नहीं है कि यह अंतर्निहित है? सभी ऐसा करते हैं कि समुदाय एक ऐसी विधि के विभिन्न संस्करण बनाता है जिसे हर कोई (या लगभग सभी) एक ही तरह से व्यवहार करने की उम्मीद करते हैं।
स्क्रेच

रास्ते से बहस करने की कोशिश नहीं करना, आपकी बात पूरी तरह से वैध है। बस इसके पीछे के कारण को समझने की कोशिश कर रहे हैं। तार्किक रूप से एक ऐतिहासिक या प्रदर्शन का कारण होना चाहिए ...
scharette

@ संचरित्र: इसका कारण विधि को यथासंभव सामान्य उद्देश्य बनाना है। जैसा कि आप अपने चुने हुए विधि हस्ताक्षर पाते हैं, बेहतर है, यह कई सीमांकक के लिए काम नहीं करेगा। Microsoft का संस्करण एकाधिक सीमांकक के साथ-साथ आपके एकल सीमांकक के लिए भी काम करेगा।
रॉबर्ट हार्वे

@RobertHarvey खैर दोनों संभव नहीं होगा? मान लीजिए कि उपरोक्त उत्तर में विस्तार विधि Stringकक्षा का हिस्सा थी , दोनों संभव होंगे। क्या मै गलत हु ?
scharette

मुझे लगता है कि आप इस बिंदु को याद कर रहे हैं। आपका अधिभार केवल एक सीमांकक की अनुमति देता है। Microsoft का अधिभार एक से अधिक अनुमति देता है। आप कई बार अपने अधिभार को नहीं बुला सकते हैं और समान परिणाम प्राप्त कर सकते हैं; यह कैसे काम करता है।
रॉबर्ट हार्वे

1

अलग-अलग भाषाओं में निहित रूपांतरण और ओवरलोडिंग के लिए कुछ अलग नियम हैं, और .NET फ्रेमवर्क को उनमें से किसी के साथ प्रयोग करने योग्य बनाया गया है। Option Strict OffVB.NET की बोली में, प्रकार का मान Stringएक फ़ंक्शन को पास किया जा सकता है जो स्ट्रिंग पर Char[]कॉल करने के बराबर व्यवहार के साथ अपेक्षा करता है ToCharArray()

मुझे लगता है कि ऐसा करने के लिए समझदार बात के लिए अलग नामों की हो गया होता Split(जो एक एकल स्वीकार करता है Charया Stringऔर) SplitMulti(जो एक को स्वीकार करेंगे Char[]या String[]), लेकिन नेट कभी कभी अकेला अधिक भार के संचालन के विभिन्न प्रकार के लेने के लिए का उपयोग कर के पक्ष में रहा है। दुर्भाग्य से, मैं String.Splitकिसी भी उपयोग परिदृश्यों को समायोजित करने के लिए उपयोग करने का कोई तरीका नहीं जानता हूं, जो प्रत्येक के लिए अलग-अलग विभाजित करके विभिन्न प्रकार के सीमांकक को अलग करने की आवश्यकता होगी।

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


1
.NET कभी-कभी विभिन्न प्रकार के कार्यों को लेने के लिए अकेले ओवरलोडिंग का उपयोग करने के पक्ष में लगता है। तो सच ...
scharette
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.