2013-05-16 16 views
5

मेरे पास स्ट्रिंग क्लास के लिए एक सरल विस्तार विधि है जो स्ट्रिंग से सभी गैर संख्यात्मक वर्णों को पट्टी कर देगी। तो अगर मेरे पास एक स्ट्रिंग है उदाहरण के लिए एक फोन नंबर जैसे "(555) 215-4444" यह इसे "5552154444" में परिवर्तित कर देगा। ऐसा लगता है:विस्तार विधि में शून्य को संभालना

public static string ToDigitsOnly(this string input) 
{ 
    Regex digitsOnly = new Regex(@"[^\d]"); 
    return digitsOnly.Replace(input, String.Empty); 
} 

मैं सोच रहा हूं कि यहां शून्य मूल्य को संभालने का सबसे शानदार तरीका क्या है? क्या इन मामलों में पालन करने के लिए एक सामान्य पैटर्न है, जैसे कि शून्य न हो जाने पर शून्य मूल्य वापस लौटाएं? ऐसा लगता है क्योंकि मैं स्ट्रिंग क्लास को विस्तारित कर रहा हूं, इसलिए मैं शून्य मानों को अनुमति देना चाहता हूं और एक बहस अपवाद नहीं फेंक सकता हूं (क्योंकि जब मैं इसका उपयोग करता हूं तो मैं वास्तव में बहस में गुजर रहा हूं ...)? लेकिन कुछ तर्क दे सकते हैं कि मुझे 'सामान्य' विधि की तरह अपवाद फेंकना चाहिए। आप यहां क्या सबसे अच्छा अभ्यास कर रहे हैं?

धन्यवाद!

+1

मैं एक सामान्य की तरह विस्तार विधि का इलाज होता कर सकते हैं। यह लोगों को कोड पढ़ने के तरीके को साफ करने का एक तरीका है। स्ट्रिंगफंक्शन की बजाय। टोडिगिट्स केवल आप इसे छोटा करने के लिए छोटा करते हैं। टोडडिग्स केवल(), इसलिए यदि आप एक में अपवाद फेंक देंगे, तो इसे दूसरे में फेंक दें। –

+1

यदि शून्य आपके आवेदन में मान्य/अपेक्षित मान है, तो शून्य वापस करें। यदि नहीं, तो अपवाद फेंक दें। व्यक्तिगत रूप से मैं यहां एक ArgumentException फेंक देंगे। – JosephHirn

+2

एक साइड नोट के रूप में; आपको यहां एक रेगेक्स की आवश्यकता नहीं है 'स्ट्रिंग.जॉइन ("", इनपुट। जहां (char.IsDigit)) ' – I4V

उत्तर

9

आप कम से कम आश्चर्य की बात है के सिद्धांत का पालन कर सकते हैं: उपयोग पैटर्न LINQ में लागू:

public static string ToDigitsOnly(this string input) 
{ 
    if(input == null) 
      throw new ArgumentNullException("input"); 

    Regex digitsOnly = new Regex(@"[^\d]"); 
    return digitsOnly.Replace(input, String.Empty); 
} 

आप, विधि का उपयोग कर सकते हैं proposed by Jon Skeet। यह आपका चेक कम हो जाएगा बस

input.ThrowIfNull("input"); 

इसके अलावा जॉन एक अच्छा अनुभाग 10.2.4 गहराई में में सी # एक अशक्त संदर्भ पर एक विधि कॉलिंग, बोली है:

तुच्छता के लिए जाँच एक ईमानदार डेवलपर के रूप में, मुझे यकीन है कि आपके उत्पादन विधियां हमेशा कार्यवाही से पहले अपने तर्कों की वैधता की जांच करें। एक सवाल यह है कि स्वाभाविक रूप से इस quirky विस्तार विधियों की विशेषता से उत्पन्न होता है, जब पहले तर्क शून्य होता है (माना जाता है कि यह होना नहीं है)। क्या यह ArgumentNullException होना चाहिए, जैसे कि यह एक सामान्य तर्क था, या इसे होना चाहिए NullReferenceException, जो होता है यदि एक्सटेंशन विधि प्रारंभ करने के लिए एक उदाहरण विधि थी? मैं पूर्व की अनुशंसा करता हूं: यह अभी भी एक तर्क है, भले ही एक्सटेंशन विधि वाक्यविन्यास स्पष्ट नहीं करता है।

मैं के रूप में (और से मेरा व्यक्तिगत अनुभव) इस सिफारिश देखें: यह हमेशा अशक्त के लिए जाँच करने के लिए बेहतर है, विशेष रूप से स्थिर तरीकों के लिए और शून्य मान पर भरोसा करने की नहीं है। एक अपवाद केवल तभी होता है जब यह आपकी विधि का सही उद्देश्य है, उदाहरण के लिए ThrowIfNull या IsNullOrEmpty विस्तार विधियां।

+0

LINQ विधियों में वस्तुतः कभी भी कोई आउटपुट नहीं होता है, जब वे शून्य पैरामीटर होते हैं तो वे समझदारी से प्रदान कर सकते हैं। यह मामला यहां नहीं है, इसलिए यह उचित तुलना नहीं है। – Servy

+0

@ सर्वी क्षमा करें, बहस नहीं करना चाहते, लेकिन वह क्यों है? 'MyString.Where (char.IsDigit)' और 'myString.ToDigitsOnly() 'में क्या अंतर है? –

1

जब तक आप व्यवहार को अच्छी तरह से संवाद नहीं करते हैं, तब तक वास्तव में कोई फर्क नहीं पड़ता है (ताकि अंतिम उपयोगकर्ता जानता है कि क्या उम्मीद करनी है)।

अपेक्षित व्यवहार को संवाद करने के लिए अंतर्निहित XML Documentation Comments का उपयोग करने पर विचार करें।

/// <exception cref="ArgumentNullException">argument is null.</exception> 
public string Example(string argument) 
{ 
    if (argument == null) 
     throw new ArgumentNullException(); 
    return argument.ToString(); 
} 
कई उदाहरण के लिए

MSDN देखें प्रलेखन:

1

मान लीजिए मैं इस है:

class A 
{ 
    public void F() 
    { 
     //do stuff 
    } 
} 

अगर मैं तो चलाने निम्नलिखित कोड, क्या होता है?

A a = null; 
a.F(); 

आपको NullReferenceException मिलता है। तो मैं कहूंगा कि बराबर विस्तार विधि लिखने का उचित तरीका निम्नानुसार होगा।

class A 
{ 
} 

static class AExtensions 
{ 
    void F(this A a) 
    { 
     if (a == null) 
     { 
      throw new NullReferenceException(); 
     } 
     //do stuff 
    } 
} 

हालांकि, .NET इस पर मुझसे असहमत है। .NET में मानक को ArgumentException फेंकना है - इसलिए इसके बजाय ऐसा करना सबसे अच्छा है।

+0

मैं इसकी अनुशंसा नहीं करता। आप उस विधि को 'AExtensions.F (शून्य)' के साथ कॉल कर सकते हैं। जब कोई 'शून्य' पैरामीटर पारित होता है तो कोई 'ArgumentNullException' की अपेक्षा करेगा। –

+1

@ जिम मिशेल ट्रू। मैं 99% समय का विस्तार विस्तार विधियों के रूप में करता हूं जैसे कि वे उस प्रकार के सदस्य थे जिन पर वे लागू होते हैं। जिस मामले में आप उन्हें एक स्थिर विधि की तरह कहते हैं वह वैध है हालांकि वैध है। हालांकि ArgumentException का उपयोग करने में वास्तव में कुछ भी गलत नहीं है। मुझे लगता है कि अगर .NET ऐसा कर रहा है तो यह जाने का रास्ता है। –

+0

'NullReferenceException' फेंकने वाली दूसरी समस्या यह है कि यह वास्तव में संवाद नहीं करता कि त्रुटि का स्रोत क्या है। वास्तविक त्रुटि कॉल साइट पर है, जहां एक शून्य पैरामीटर पारित किया जाता है। यदि आपका कोड एनआरई फेंकता है (जो वैसे भी करेगा, अगर आपने इसे एक्सेस करने का प्रयास किया है), तो ग्राहक को विश्वास है कि त्रुटि विस्तार विधि में है। यह विशेष रूप से सच है यदि ग्राहक पुस्तकालय का उपयोग कर रहा है जिसके लिए उसके पास स्रोत नहीं है। 'ArgumentNullException' क्लाइंट * बिल्कुल * समस्या क्या बताता है। –

1

सरल; स्ट्रिंग के लिए एक और तरीका बनाएं, IsInValid()

सार्वजनिक स्थैतिक बूल IsInValid (यह स्ट्रिंग एस) { वापसी (s == null) || (एस लम्बाई == 0); }

उपयोग जहाँ आप जाँच करना चाहते हैं ...

इसके अलावा, आप इस एक्सटेंशन का उपयोग कहीं भी

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