2012-07-04 30 views
11

मेरे पास IEnumerable पैरामीटर है जो खाली होने की आवश्यकता है। यदि नीचे दिए गए की तरह पूर्व शर्त है तो संग्रह के दौरान गणना की जाएगी। लेकिन अगली बार जब मैं इसका संदर्भ दूंगा तो इसे फिर से समझा जाएगा। (ए "IEnumerable के संभावित कई गणन" Resharper में चेतावनी।)अनुबंध पूर्व शर्त के कारण IENumerable एकाधिक गणना

void ProcessOrders(IEnumerable<int> orderIds) 
{ 
    Contract.Requires((orderIds != null) && orderIds.Any()); // enumerates the collection 

    // BAD: collection enumerated again 
    foreach (var i in orderIds) { /* ... */ } 
} 

इन समाधानों Resharper खुश कर दिया लेकिन संकलन नहीं होगा:

अन्य समाधानों
// enumerating before the precondition causes error "Malformed contract. Found Requires 
orderIds = orderIds.ToList(); 
Contract.Requires((orderIds != null) && orderIds.Any()); 
--- 
// enumerating during the precondition causes the same error 
Contract.Requires((orderIds != null) && (orderIds = orderIds.ToList()).Any()); 

हैं जो मान्य होगा, लेकिन शायद नहीं हमेशा आईसीओलेक्शन या आईलीस्ट का उपयोग करने जैसे आदर्श, या एक सामान्य if-null-throw-upgrade प्रदर्शन करना।

क्या कोई ऐसा समाधान है जो मूल अनुबंध में कोड अनुबंध और आईनेमरेबल्स के साथ काम करता है? यदि नहीं तो क्या किसी ने इसके आसपास काम करने के लिए एक अच्छा पैटर्न विकसित किया है?

+3

मुझे लगता है कि यह शायद सिर्फ एक बुरा विचार है एक अनुबंध एक IEnumerable पर निर्भर है करने के लिए - परिभाषा से IEnumerables के रूप में साइड इफेक्ट लगा सकता है। –

+0

अब तक मैंने एक कामकाज के रूप में आईसीओलेक्शन का उपयोग किया है और कभी भी कोई समस्या नहीं आई है, हालांकि अगर मैं IENumerables के लिए कोई समाधान कर रहा हूं तो मैं उत्सुक हूं। – Keith

उत्तर

7

उपयोग इस तरह के Contract.Exists रूप IEnumerable है, के साथ काम करने के लिए डिजाइन तरीकों में से एक:

निर्धारित करता है तत्वों का एक संग्रह के भीतर एक तत्व एक समारोह के भीतर मौजूद है या नहीं।

रिटर्न

अगर सच और केवल विधेय संग्रह में प्रकार टी के किसी भी तत्व के लिए सच लौटाता है यदि।

तो आपकी भविष्यवाणी true वापस आ सकती है।


Contract.Requires(orderIds != null); 
Contract.Requires(Contract.Exists(orderIds,a=>true)); 
+2

क्या यह 'IENumerable' का भी आकलन नहीं करेगा? – Rawling

+1

केवल तभी यदि आप ए) रनटाइम जांच सक्षम कर चुके हैं, और बी) "Quantifiers छोड़ें" चुना नहीं है। (हालांकि, इस तरह के मामले में, मैं दो 'आवश्यकता' में विभाजित करने की सिफारिश करता हूं) –

+0

आह ठीक है। तो यह कहना सही होगा कि न तो मूल कोड और न ही आपका कोड _actually_ एक गणना (मॉड्यूल आपके ए और बी ऊपर) का कारण बनता है, लेकिन रीशर्पर को मूल कोड में इसका एहसास नहीं होता है, और आपका कोड बस इसे एक रूप में रखता है आरएस अनदेखा करता है? – Rawling