2010-03-15 10 views
5

निम्नलिखित हस्ताक्षरTryXxxx विधि गलत होने पर आउट पैरामीटर के लिए मानक व्यवहार क्या है?

bool TryXxxx(object something, out int toReturn) 

क्या यह अगर TryXxxx रिटर्न गलत होने की toReturn के लिए स्वीकार्य है के साथ एक विधि मान लिया जाये?

इसमें यह बताया गया है कि toReturn का उपयोग कभी नहीं किया जाना चाहिए यदि TryXxxx विफल रहता है तो इससे कोई फर्क पड़ता है?

यदि toReturn एक संलयन प्रकार था, तो यह शून्य वापस लौटने का अर्थ होगा। लेकिन int शून्य नहीं है और मैं इसे मजबूर नहीं करना चाहता हूं।

यदि toReturnTryXxxx विफल रहता है तो हम हमेशा उस स्थिति को रखने का जोखिम लेते हैं जहां एक ही चीज़ को इंगित करने के लिए 2 मानों पर विचार किया जा सकता है। यदि यह 'डिफ़ॉल्ट' मान मान्य प्रतिक्रिया के रूप में वापस किया गया था (जब TryXxxx सत्य लौटाता है) तो मैं संभावित संभावित भ्रम की ओर अग्रसर हो सकता हूं।

एक कार्यान्वयन बिंदु से यदि ऐसा लगता है कि यह toReturn होने जैसा लगता है तो [ny] मान सबसे आसान है, लेकिन क्या विचार करने के लिए और कुछ महत्वपूर्ण है?

उत्तर

6

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

ध्यान दें कि int.TryParse और Dictionary.TryGetValue डू जैसी विधियां हैं।

+0

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

+0

अगर उपभोक्ता को झूठी वापसी का प्रयास करने का कोई कारण नहीं है तो उपभोक्ता के बारे में सोचा नहीं था। –

4

यह default(int) हो सकता है:

bool TryXxxx(object something, out int toReturn) 
{ 
    toReturn = default(int); 
    return false; 
} 
2

मैं default कहेंगे, लेकिन वास्तव में इससे कोई फर्क नहीं करना चाहिए। TryX के साथ सम्मेलन यह है कि कॉलर को वापसी मान की जांच करनी चाहिए और विधि सही होने पर केवल आउट पैरामीटर का उपयोग करना चाहिए।

2

असल में यह कुछ है। मैं इसे "परिभाषित नहीं" के रूप में दस्तावेज करता हूं। समझदार मान हैं:

  • डिफ़ॉल्ट()
  • MINVALUE, MaxCValue, NEWVALUE, अशक्त
  • नेन मूल्य (Double.NaN) (नई पूर्णांक() के रूप में)

लेकिन सामान्य रूप में, मैं वास्तव में "परिभाषित नहीं" कहता हूं और लोगों को कुछ नहीं देता जो वे भरोसा करने की कोशिश कर सकते हैं।

+0

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

0

1) दरअसल, मुझे लगता है कि इससे कोई फर्क नहीं पड़ता क्योंकि आपको हमेशा मूल्य को संसाधित करने से पहले उन विधियों के बूलियन परिणाम की जांच करनी चाहिए। TryXXX विधियों के लिए यही है।

2) हालांकि, ऐसे मामलों में, मैं हमेशा स्थिरता की गारंटी के लिए .NET ढांचे में कार्यान्वयन का संदर्भ देता हूं।और परावर्तक में शीघ्रता से अवलोकन से पता चलता है कि Int32 प्रकार रिटर्न 0 यदि पार्स विफल रहा है:,

internal static unsafe bool TryParseInt32(string s, NumberStyles style, NumberFormatInfo info, out int result) 
{ 
    byte* stackBuffer = stackalloc byte[1 * 0x72]; 
    NumberBuffer number = new NumberBuffer(stackBuffer); 
    result = 0; // <== see here! 
    if (!TryStringToNumber(s, style, ref number, info, false)) 
    { 
     return false; 
    } 
    if ((style & NumberStyles.AllowHexSpecifier) != NumberStyles.None) 
    { 
     if (!HexNumberToInt32(ref number, ref result)) 
     { 
      return false; 
     } 
    } 
    else if (!NumberToInt32(ref number, ref result)) 
    { 
     return false; 
    } 
    return true; 
} 

हालांकि कार्यान्वयन विवरण नहीं जानने, यह अभी भी हो सकता है कि पार्स समस्या तब होती है जब एक मूल्य पहले से ही सौंपा गया है (आंशिक रूप से)। इस मामले में, मान अब 0 नहीं हो सकता है। इसलिए, आपको हमेशा "समाधान" से चिपकना चाहिए 1)! :-)

gehho।

0

.net से पहले, सामान्य पैटर्न TryXX विधियों को केवल पास-बाय-रेफरेंस तर्क को अनमोडिफाइड छोड़ने के लिए था। यह एक बहुत ही उपयोगी पैटर्न था, क्योंकि यह है कि कोड जिसका कोई डिफ़ॉल्ट मान का उपयोग करने की तरह कुछ कर सकता है चाहता था मतलब:

MyNum = 5; 
TryParsing(myString, &myNum); 

कोड था कि एक डिफ़ॉल्ट मान का उपयोग नहीं करना चाहता इस्तेमाल कर सकते हैं, जबकि:

if (TryParsing(myString, &myNum)) 
{ .. code that uses myNum .. } 
else 
{ .. code that doesn't use myNum .. } 

पूर्व उपयोग में, कॉलिंग कोड को सुनिश्चित करना होगा कि myNum कॉल से पहले शुरू किया गया था, लेकिन TryParsing वापसी मूल्य के बारे में चिंता करने की आवश्यकता नहीं होगी। बाद के उपयोग में, कॉलिंग कोड को वापसी मूल्य के बारे में चिंता करनी होगी, लेकिन कॉल से पहले myNum प्रारंभ करना होगा। TryParsing दिनचर्या को स्वयं चिंता करने की आवश्यकता नहीं होगी कि किस उद्देश्य का इरादा था।

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

पर विचार करें, उदाहरण के लिए, उस शैली की एक विधि प्रकार fooStruct का एक तर्क का इस्तेमाल किया है, और fooStruct एक निर्माता की तरह देखा था:

fooStruct(string st) 
{ 
    fooStruct.TryParse(st, out this); 
} 

संकलक इस तरह के एक निर्माता के साथ पूरी तरह खुशी होगी, जब से यह "निश्चित रूप से" this लिखता है। दूसरी ओर, यदि कुछ अन्य कोड है:

while(someCondition) 
{ 
    var s = new fooStruct(someString); 
    ... 
} 

एक उम्मीद कर सकते हैं कि s या तो एक प्रारंभ संरचना का आयोजन करेगा (यदि someString मान्य है) या खाली हो (अगर यह नहीं है)। उस कोड के बारे में कुछ भी सुझाव नहीं देगा कि s लूप की पुनरावृत्ति के बीच अपना मान रख सकता है। फिर भी, यह वही है जो संभवतः होगा।

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