2009-07-21 21 views
5

तो मैं अपने निर्माता में एक भी स्ट्रिंग पैरामीटर के साथ एक वर्ग है के तर्कों को मान्य करने का सही तरीका क्या है:एक निर्माता

public MyClass(string name) 
{ 
    this.Name = name; 
} 

लेकिन मैं कभी नहीं कुछ एक MyClass का एक उदाहरण आरंभ के बारे में चिंता करना चाहते हैं नाम के साथ जो शून्य या शून्य लंबाई स्ट्रिंग है। पैरामीटर को सत्यापित करने के लिए सबसे अच्छा क्या था? किसी संपत्ति या विधि के साथ आप हमेशा कुछ भी नहीं कर सकते हैं, शून्य वापस कर सकते हैं, या अमान्य तर्क प्रदान किए जाने पर कुछ भी सेट नहीं कर सकते हैं। लेकिन एक बार कन्स्ट्रक्टर को ऑब्जेक्ट का उदाहरण कहा जाता है, इस पर ध्यान दिए बिना कि यह वैध तर्क पारित किया गया है या नहीं।

एक अपवाद फेंक रहा है जैसा कि नीचे दिखाया गया है? या क्या कोई और तरीका है जो अधिक पसंद किया जाता है?

public MyClass(string name) 
{ 
    if (name == null | name == "") throw new ArgumentException("Name can not be null or blank", "name"); 

    this.Name = name; 
} 

बेशक मैं हमेशा "बेनाम MyClass" की तरह कुछ डिफ़ॉल्ट करने के लिए नाम सेट कर सकते हैं यदि आर्ग्यूमेंट अवैध है, लेकिन इस मामले में मैं नहीं बल्कि सिर्फ तो गलत नाम को रोकने चाहते हैं कुछ वैकल्पिक व्यवहार ग्रहण करने के लिए कोशिश कर रहा।

उत्तर

7
  1. एक ArgumentNullException
  2. दस्तावेज़ कि ctor फेंकता ArgumentNullException अगर नाम आप Code Contracts का उपयोग कर रहे हैं, तो आपके पैरामीटर सत्यापन के बाद एक Contract.EndContractBlock() पंक्ति जोड़ें null
  3. है फेंक।

संपादित करें: इस के बजाय:

if (name == null || name == "") 

उपयोग करें:

if (string.IsNullOrEmpty(name)) 
+0

बहुत करते समय सावधान रहें कंस्ट्रक्टर्स में अपवाद फेंक आप लीक संसाधनों अगर यो के साथ खत्म हो सकता है आपने संसाधनों को हथियाने/स्मृति आवंटित करना शुरू कर दिया है – Matt

+0

किसी भी तरह से, यह नहीं किया जाएगा || (तार्किक या) और नहीं | (बिटवाईर या)? बस सोच रहा। –

+0

@ ब्लेनक, हाँ, मैंने कॉपी और पेस्ट का इस्तेमाल किया। आश्चर्यजनक रूप से मेरा उपयोग ओपी की बग से वास्तव में प्रभावित नहीं था। :) –

1

आप या तो नाम को डिफ़ॉल्ट रूप से सेट कर सकते हैं या अपवाद फेंक सकते हैं। कुछ और सिर्फ सादा गलत है क्योंकि यह एक गैर-मान्य स्थिति वाला ऑब्जेक्ट बनाएगा।

1

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

यदि कोई नाम नहीं पारित करना ऑब्जेक्ट बनाने का एक वैध तरीका है, तो पैरामीटर रहित कन्स्ट्रक्टर प्रदान करें।

3

यहां पसंदीदा समाधान अपवाद फेंकना है। जल्दी विफल, अक्सर विफल। दस्तावेज़ बनाएं कि आपके कन्स्ट्रक्टर के लिए वैध पैरामीटर क्या हैं और यह अमान्य पैरामीटर पर ArgumentNullException या ArgumentOutOfRangeException फेंकता है।

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

मैंने कुछ सहकर्मियों के साथ एक तर्क सुलझाने के लिए थोड़ी देर पहले question से पूछा।

"लेकिन एक बार एक निर्माता को ऑब्जेक्ट का उदाहरण कहा जाता है, भले ही यह वैध तर्क पारित किया गया हो।"

वस्तु बनाई गई है (यानी, गैर-शून्य) को केवल तभी निर्माता सामान्य रूप से देता है।

1

वहाँ एक गार्ड उपयोगिता वर्ग है कि आप किसी भी विधि को पारित कर दिया तर्क मान्य उपयोगी लग सकते है।

वर्ग avaialable है here प्रणाली का उपयोग करते हुए; System.Globalization उपयोग करते हुए;।

namespace Microsoft.Practices.Mobile.CompositeUI.Utility 
    { 
     /// <summary> 
     /// Common guard clauses. 
     /// </summary> 
     public static class Guard 
     { 


    /// <summary> 
     /// Checks a string argument to ensure it isn't null or empty. 
     /// </summary> 
     /// <param name="argumentValue">The argument value to check.</param> 
     /// <param name="argumentName">The name of the argument.</param> 
     public static void ArgumentNotNullOrEmptyString(string argumentValue, string argumentName) 
     { 
      ArgumentNotNull(argumentValue, argumentName); 

      if (argumentValue.Trim().Length == 0) 
       throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Properties.Resources.StringCannotBeEmpty, argumentName)); 
     } 

     /// <summary> 
     /// Checks an argument to ensure it isn't null. 
     /// </summary> 
     /// <param name="argumentValue">The argument value to check.</param> 
     /// <param name="argumentName">The name of the argument.</param> 
     public static void ArgumentNotNull(object argumentValue, string argumentName) 
     { 
      if (argumentValue == null) 
       throw new ArgumentNullException(argumentName); 
     } 

     /// <summary> 
     /// Checks an Enum argument to ensure that its value is defined by the specified Enum type. 
     /// </summary> 
     /// <param name="enumType">The Enum type the value should correspond to.</param> 
     /// <param name="value">The value to check for.</param> 
     /// <param name="argumentName">The name of the argument holding the value.</param> 
     public static void EnumValueIsDefined(Type enumType, object value, string argumentName) 
     { 
      if (Enum.IsDefined(enumType, value) == false) 
       throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, 
        Properties.Resources.InvalidEnumValue, 
        argumentName, enumType.ToString())); 
     } 

     /// <summary> 
     /// Verifies that an argument type is assignable from the provided type (meaning 
     /// interfaces are implemented, or classes exist in the base class hierarchy). 
     /// </summary> 
     /// <param name="assignee">The argument type.</param> 
     /// <param name="providedType">The type it must be assignable from.</param> 
     /// <param name="argumentName">The argument name.</param> 
     public static void TypeIsAssignableFromType(Type assignee, Type providedType, string argumentName) 
     { 
      if (!providedType.IsAssignableFrom(assignee)) 
       throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, 
        Properties.Resources.TypeNotCompatible, assignee, providedType), argumentName); 
     } 
    } 
}