ठोस जवाब
यह पूरी तरह स्वीकार्य है: नेट स्रोत कोड की स्थिति गिर्द घूमती है।
उदाहरण के लिए, StringBuilder
source code में VerifyClassInvariant()
नामक एक विधि है जिसे यह 18 बार कॉल करता है। विधि सिर्फ शुद्धता की जांच करता है।
private void VerifyClassInvariant()
{
BCLDebug.Correctness((uint)(m_ChunkOffset + m_ChunkChars.Length) >= m_ChunkOffset, "Integer Overflow");
StringBuilder currentBlock = this;
int maxCapacity = this.m_MaxCapacity;
for (; ;)
{
// All blocks have copy of the maxCapacity.
Contract.Assert(currentBlock.m_MaxCapacity == maxCapacity, "Bad maxCapacity");
Contract.Assert(currentBlock.m_ChunkChars != null, "Empty Buffer");
Contract.Assert(currentBlock.m_ChunkLength <= currentBlock.m_ChunkChars.Length, "Out of range length");
Contract.Assert(currentBlock.m_ChunkLength >= 0, "Negative length");
Contract.Assert(currentBlock.m_ChunkOffset >= 0, "Negative offset");
StringBuilder prevBlock = currentBlock.m_ChunkPrevious;
if (prevBlock == null)
{
Contract.Assert(currentBlock.m_ChunkOffset == 0, "First chunk's offset is not 0");
break;
}
// There are no gaps in the blocks.
Contract.Assert(currentBlock.m_ChunkOffset == prevBlock.m_ChunkOffset + prevBlock.m_ChunkLength, "There is a gap between chunks!");
currentBlock = prevBlock;
}
}
संवाद
यह समूह दावे या अपवाद के लिए ठीक एक स्थिर विधि में, बल्कि उन्हें बाहर लेखन स्पष्ट रूप से है?
हां। ठीक है।
... ऐसा लगता है कि पूर्व शर्त को किसी विधि के सटीक उद्देश्य को दस्तावेज़ में मदद करने में मदद करनी चाहिए।
विधि है कि assert
या Exception
बयान लपेटता के नाम आवरण के इरादे से संवाद करना चाहिए। इसके अलावा, अगर पाठक विनिर्देशों को जानना चाहता है, तो वह विधि के कार्यान्वयन को देख सकती है (जब तक कि यह बंद स्रोत न हो।)
क्या यह अच्छा या बुरा अभ्यास माना जाता है, और क्यों?
यह का एक सेट रैप करने के लिए अच्छा व्यवहार है संबंधित या आम तौर पर किसी अन्य विधि में asserts
पुन: उपयोग किया, क्योंकि यह दोनों पठनीयता में सुधार और रखरखाव की सुविधा कर सकते हैं।
क्या यह एक आम विरोधी पैटर्न है?
इसके विपरीत, वास्तव में। आप ऐसा कुछ देख सकते हैं और यह वास्तव में सहायक और अनुशंसित है क्योंकि यह अच्छी तरह से संवाद करता है।
private void IfNotValidInputForPaymentFormThenThrow(string input)
{
if(input.Length < 10 || input.Length)
{
throw new ArgumentException("Wrong length");
}
// other conditions omitted
}
यह इतना है कि फोन करने वाले को जानता है आप मना रहे हैं विधि के अंत तक ThenThrow
जोड़ने के लिए एक अच्छा विचार है। अन्यथा, आप bool
वापस लौटना चाहेंगे और कॉलर को यह तय करने दें कि स्थिति विफल होने पर क्या करना है।
private bool IsValidInputForPaymentForm(string input)
{
if(input.Length < 10 || input.Length)
{
return true;
}
else
{
return false;
}
// other conditions omitted
}
फिर बुला कोड फेंक कर सकते हैं:
if(!IsValidInputForPaymentForm(someStringInput)
{
throw new ArgumentException();
}
या, यहाँ another example from the .NET source कि एक अपवाद फेंकता है तो कुछ शर्तें असफल है
// Allow nulls for reference types and Nullable<U>,
// but not for value types.
internal static void IfNullAndNullsAreIllegalThenThrow<T>(
object value, ExceptionArgument argName)
{
// Note that default(T) is not equal to null
// for value types except when T is Nullable<U>.
if (value == null && !(default(T) == null))
ThrowHelper.ThrowArgumentNullException(argName);
}
(
ThrowHelper
सिर्फ अपवाद फेंकता है।)
क्या ऐसा करने के लिए कोई महत्वपूर्ण कारण नहीं है?
मैं की है कि क्या सोच सकते हैं, अगर विधि नाम आप क्या जाँच कर रहे हैं की व्याख्या नहीं करता है, और वहाँ स्रोत देखने के लिए, तो आप शायद स्थिति लपेटकर से बचना चाहिए एक आसान तरीका नहीं है।
मैंने एक निश्चित उत्तर जोड़ा। –
मेरे लिए, प्राथमिक अंतर पूर्व शर्त जांच का दायरा होगा। इस मामले में (क्योंकि यह एक जटिल व्यापार नियम है - "कुछ और जो वैध उपयोगकर्ता को परिभाषित करता है" - चेक किया जा रहा है) मुझे 'लपेटा/सहायक' चेक पर कोई आपत्ति नहीं होगी। हालांकि, मैं शायद अलग से शून्य की जांच करूँगा। – user2864740
@ user2864740 आप अलग से शून्य की जांच क्यों करेंगे? मेरे पास कई समूहबद्ध चेक हैं जिनके लिए पहले चरण के रूप में शून्य जांच की आवश्यकता है। –