2011-01-05 17 views
5

मैं Code Contracts का उपयोग Code Contracts Editor Extensions वीएस -2010 ऐड-इन के साथ कर रहा हूं। मेरे पास एक कक्षा है जो IEnumerable<T> इंटरफ़ेस लागू करती है, और मैंने GetEnumerator() विधि के लिए एक इटरेटर ब्लॉक लागू किया है। यह ऊपर, मैं निम्नलिखित विरासत में मिला अनुबंध देख सकते हैं:कोड अनुबंध: IENumerator <T> .GetEnumerator() अजीब विरासत अनुबंध?

ensures result != null ensures result.Model == ((IEnumerable)this).Model [Pure] public IEnumerator(of IBaseMessage) GetEnumerator() {

मैं पहले और तीसरे अनुबंध आवश्यकता को समझते हैं - GetEnumerator() एक अशक्त वापस कभी नहीं करना चाहिए, और यह एक पक्ष प्रभाव का कारण नहीं करना चाहिए। लेकिन दूसरी अनुबंध आवश्यकता का क्या अर्थ है? यह ModelIEnumerator<T> और IEnumerable की संपत्ति क्या है?

संपादित करें: Damien_The_Unbeliever के रूप में उसकी टिप्पणी में बताया, IEnumerable<T> और IEnumerator<T> के लिए अनुबंध, एक संविदा संदर्भ विधानसभा एक अलग फ़ाइल में स्थित हैं। वहाँ GetEnumerator() में एक अतिरिक्त अनुबंध है कि संपादक द्वारा प्रदर्शित नहीं किया जाता है

[return: Fresh] 
[Escapes(true, false), Pure, GlobalAccess(false)] 
public IEnumerator GetEnumerator() 
{ 
    IEnumerator enumerator; 
    Contract.Ensures((bool) (Contract.Result<IEnumerator>() != null), null, "Contract.Result<IEnumerator>() != null"); 
    Contract.Ensures((bool) (Contract.Result<IEnumerator>().Model == this.Model), null, "Contract.Result<IEnumerator>().Model == this.Model"); 
    Contract.Ensures((bool) (Contract.Result<IEnumerator>().CurrentIndex == -1), null, "Contract.Result<IEnumerator>().CurrentIndex == -1"); 
    return enumerator; 
} 

दिलचस्प बात यह है: Reflector का उपयोग करना (पूर्ण कोड here है) उन दो इंटरफेस के अनुबंध के disassembly में,, आप निम्न देख सकते हैं विस्तार:

Contract.Result<IEnumerator>().CurrentIndex == -1 

और कुछ additionaly रहस्यों (जैसे Fresh, Escapes और GlobalAccess विशेषताओं के रूप में)।

+1

मैं आपकी मदद नहीं कर सकता, लेकिन मुझे रुचि के कुछ क्षेत्रों की ओर इशारा करने के लिए धन्यवाद। कोड अनुबंध द्वारा उपयोग किए जाने वाले 'IENumerable' और 'IENumerable ' प्रकार C: \ Program Files \ Microsoft \ Contracts \ Contracts \ .NETFramework \ v4.0 \ mscorlib.Contracts.dll (स्थान भिन्न हो सकते हैं) से लोड किए गए हैं, और इन संस्करणों इंटरफेस (और उनके संबंधित अनुबंध वर्गों) में mscorlib से "वास्तविक" इंटरफेस की तुलना में अधिक सदस्य हैं। लेकिन अनुबंध एनोटेशन के माध्यम से भी पढ़ा है, मुझे नहीं पता कि मॉडल का उद्देश्य क्या है। –

+0

@ डेमियन: धन्यवाद, मैंने आपकी नई जानकारी के प्रति प्रश्न संपादित किया है। –

+0

क्या वह 'IENumerator' रिटर्न प्रकार अनुबंध में असली' IENumerator' इंटरफ़ेस या एक ही नाम वाला वर्ग है? यदि यह इंटरफ़ेस है तो मुझे यह भी समझ में नहीं आता कि यह क्यों संकलित करता है। – CodesInChaos

उत्तर

2

सी: \ प्रोग्राम फ़ाइलें \ माइक्रोसॉफ्ट \ अनुबंध \ Contracts.NETFramework \ v4.0 \ mscorlib.Contracts.dll (मेरी टिप्पणी में संदर्भित) से लोड कोड/अनुबंधों पर दूसरा नजर डालने के बाद।

मेरा मानना ​​है कि इसे आपके कार्यान्वयन के लिए सुरक्षित रूप से अनदेखा किया जा सकता है। ऐसा लगता है कि यह संबंधित है कि यह एक अनुबंध को परिभाषित करने की कोशिश कर रहा है (प्रभावी रूप से) जब आप अपने IEnumerator ऑब्जेक्ट के साथ पुन: प्रयास कर रहे हैं, तो यह तत्वों की एक निश्चित संख्या वापस कर देगा। ये तत्व प्रभावी रूप से "स्नैपशॉट" होते हैं जब GetEnumerator को कॉल वापस कर दिया जाता है, और रीसेट और MoveNext पर कॉल केवल तत्वों के एक ही सेट पर फिर से सक्रिय हो सकता है।

मुझे लगता है कि यह कुछ अपरिवर्तनीय गारंटी देने की कोशिश कर रहा है। मुझे नहीं पता कि क्या हम इन तरह के अनुबंधों को स्वयं लिख सकते हैं - यह ContractModel विशेषता का उपयोग करता है, जो कहीं भी दस्तावेज प्रतीत नहीं होता है, जहां तक ​​मुझे मिल सकता है।


के संबंध में immutablility, आदि:

मैं ज्यादातर लौटे IEnumerator वस्तु पर MoveNext के लिए अनुबंध देख रहा था - मूल रूप से, यह कह रहा है कि MoveNext मॉडल संपत्ति नहीं बदल सकते (हम जानते हैं कि था GetEnumerator द्वारा इसे असाइन किया गया एक ही मॉडल), और यह कि वर्तमान इंडेक्स संपत्ति 0 और मॉडल के बीच भिन्न है। लम्बाई। उसके बाद यह सिर्फ आंत महसूस/अनुमान है। मैं अनुबंध असेंबली में किसी और चीज को इंगित नहीं कर सकता जो मुझे और जानकारी देता है।

+0

मुझे पूरा यकीन नहीं है कि आप अनुबंध विच्छेदन से उस निष्कर्ष पर कैसे पहुंचे, विस्तृत करने के लिए देखभाल? क्या उन सभी अतिरिक्त गुणों को संकलक द्वारा उत्पन्न किया जा सकता है जब यह [सीपीएस] (http://en.wikipedia.org/wiki/Continuation-passing_style) का उपयोग करके एक नियमित विधि में एक इटरेटर ब्लॉक को परिवर्तित करता है? –

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