2013-11-21 10 views
58

कभी कभी Resharper के बारे में चेतावनी देते हैं:Resharper के उदाहरण कोड

IEnumerable

के संभावित कई गणन

वहाँ an SO question on how to handle this issue है, और ReSharper साइट भी बातें here बताते हैं।

IEnumerable<string> names = GetNames().ToList(); 

मेरा प्रश्न यह विशिष्ट सुझाव के बारे में है: यह अभी भी 2 के लिए-प्रत्येक छोरों में दो बार संग्रह के माध्यम से गणना का कारण नहीं बनेगा यह कुछ नमूना कोड है जो आपको बताता बजाय यह करने के लिए है?

उत्तर

146

GetNames()IEnumerable देता है। तो अगर आपको लगता है कि परिणाम की दुकान:

IEnumerable foo = GetNames(); 

तो हर बार जब आप गणना foo, GetNames() पद्धति को पुन: कहा जाता है (शाब्दिक नहीं, मैं एक लिंक है जो ठीक से विवरण बताते हैं नहीं मिल सकता है, लेकिन IEnumerable.GetEnumerator() देखें)।

Resharper समझती है और एक सूची में materializing द्वारा एक स्थानीय चर में GetNames() की गणना, उदाहरण के लिए की परिणाम स्टोर करने के लिए आप पता चलता है:

IEnumerable fooEnumerated = GetNames().ToList(); 

यह सुनिश्चित करें कि GetNames() परिणाम है कर देगा केवल एक बार गणना की गई, जब तक आप fooEnumerated देखें।

इससे कोई फर्क नहीं पड़ता क्योंकि आप आमतौर पर केवल एक बार गणना करना चाहते हैं, उदाहरण के लिए जब GetNames() एक (धीमी) डेटाबेस कॉल करता है।

क्योंकि सामग्री भौतिककृत एक सूची में परिणाम है, इससे कोई फर्क नहीं पड़ता कि आप fooEnumerated दो बार गणना करते हैं; आप एक मेमोरी सूची में दो बार फिर से चल रहे होंगे।

+0

आह संभव एकाधिक गणन! इससे स्पष्ट हुआ। – user2250250

+0

नहीं। GetEnumerator() विधि केवल फ़ोरैच लूप में ही लागू की जाएगी। वास्तविक कारण गंदे डेटा के जोखिम के लिए है। उदाहरण के लिए, GetNames() में, एक SQL क्वेरी है, लेकिन केवल क्वेरी जो IENurable लौटाती है। जब आप आमंत्रित करते हैं। टोस्टिस्ट(), आप स्मृति में सभी डेटा स्टोर करते हैं, गंदे डेटा का थोड़ा खतरा होता है।लेकिन यदि 2 लूप ऑप्रेशन के बीच अधिक समय है, तो यदि आप प्रत्येक बार डेटाबेस में SQL को उत्तेजित करते हैं, तो गंदे डेटा का एक बड़ा खतरा होता है। –

+0

@SunRobin यह एक ऐसा उत्तर है जो सत्य को सरल रूप में प्रस्तुत करता है, जैसा कि इसमें भी उल्लेख किया गया है। मैं इसे अभी तक सुधारने के लिए अभी तक नहीं मिला है। "गंदे डेटा" के आपके उपयोग के लिए कुछ और स्पष्टीकरण की आवश्यकता हो सकती है। – CodeCaster

4

हां, आप इसे बिना किसी संदेह के दो बार गणना करेंगे। लेकिन मुद्दा यह है कि GetNames() एक आलसी linq क्वेरी देता है जो गणना करने के लिए बहुत महंगा है, तो यह दो बार पर ToList() या ToArray() पर कॉल किए बिना गणना करेगा।

7

GetNames() दो बार नहीं कहा जाता है। IEnumerable.GetEnumerator() के कार्यान्वयन को प्रत्येक बार जब आप foreach के साथ संग्रह की गणना करना चाहते हैं तो उसे कॉल किया जाता है। यदि IEnumerable.GetEnumerator() के भीतर कुछ महंगी गणना की जाती है तो यह विचार करने का एक कारण हो सकता है।

7

मुझे यह कई समझाओं को समझने का सबसे अच्छा और आसान तरीका है।

सी # LINQ: IEnumerable

की

https://helloacm.com/c-linq-possible-multiple-enumeration-of-ienumerable-resharper/

+0

आप यहां अपने लिंक के विशेष बिंदु इंगित कर सकते हैं .. लेकिन लिंक अच्छा है -> +1 – LuckyLikey

+0

यह एक उदाहरण के साथ एक महान और आसान व्याख्या है! – decompiled