2010-03-15 17 views
34

में ऑब्जेक्ट्स बनाने के लिए सर्वोत्तम अभ्यास या ऑब्जेक्ट्स से निपटने के लिए सबसे अच्छा अभ्यास क्या है? क्या हमें लूप के बाहर एक ऑब्जेक्ट बनाना चाहिए और इसे फिर से फिर से बनाना चाहिए (नया उपयोग कर ...) या प्रत्येक लूप पुनरावृत्ति के लिए नया बनाएं?
उदाहरण:/foreach loops

foreach(var a in collection) 
{ 
    SomeClass sc = new SomeClass(); 
    sc.id = a; 
    sc.Insert(); 
} 

या

SomeClass sc = null; 
foreach(var a in collection) 
{ 
    sc = new SomeClass(); 
    sc.id = a; 
    sc.Insert(); 
} 

कौन सा बेहतर है?

उत्तर

67

पहला तरीका बेहतर है क्योंकि यह चर के इच्छित उद्देश्य को स्पष्ट रूप से व्यक्त करता है और त्रुटियों को गलती से इच्छित उद्देश्य के बाहर किसी ऑब्जेक्ट का उपयोग करने से रोकता है।

दूसरे फॉर्म का उपयोग करने के लिए एक कारण यह है कि यदि आप लूप से बाहर निकलना चाहते हैं और अभी भी उस ऑब्जेक्ट का संदर्भ है जो आप लूप में पहुंचे थे।

दूसरा फॉर्म चुनने का एक बुरा कारण प्रदर्शन है। यह पहली नज़र में प्रतीत हो सकता है कि दूसरी विधि कम संसाधनों का उपयोग करती है या आप केवल एक वस्तु बना रहे हैं और इसका पुन: उपयोग कर रहे हैं। यह मामला यहां नहीं है। लूप के अंदर एक चर की बार-बार घोषणा किसी भी अतिरिक्त संसाधन या घड़ी चक्र का उपभोग नहीं करती है, इसलिए आपको लूप के बाहर घोषणा खींचने से कोई प्रदर्शन लाभ नहीं मिलता है।

+3

+1 - वस्तुओं को केवल घोषित किया जाना चाहिए कि उन्हें कहां और कब आवश्यकता हो। यदि आपको int लूप में int की आवश्यकता है तो इसे फंक्शन बॉडी के शीर्ष पर नहीं लूप के लिए घोषित करें। कोड पूर्ण :) देखें। – JonH

+1

नेट वैरिएबल घोषणा में विधि के लिए वास्तव में मेटा-डेटा है। कोड में चर बनाया गया वास्तविक स्थान केवल संकलक के लिए दायरा को प्रभावित करता है ... दूसरे शब्दों में, इन दो उदाहरणों के बीच कोई प्रदर्शन अंतर नहीं है। –

+2

एक बार एक बार, आईएल में उन दो लूप (जावा और सी ++ के साथ) के बीच उत्पादित मामूली अंतर थे, हालांकि देखभाल करने के लिए पर्याप्त नहीं था। सुनिश्चित नहीं है कि वर्तमान कंपाइलर्स ने इसे बदल दिया है या यदि सीएलआर अतिरिक्त आईएल को दूर करता है। –

4

मुझे यकीन है कि कोई एमएसआईएल विश्लेषण को मिटा सकता है, लेकिन व्यावहारिक रूप से निष्पादन या प्रदर्शन में कोई स्पष्ट अंतर नहीं है। एकमात्र चीज जिसे आप प्रभावित कर रहे हैं वह ऑब्जेक्ट संदर्भ का भंडारण है।

मैं कहता हूं कि इसे साफ और सरल रखें; लूप के अंदर चर घोषित करें। इस अभ्यास में खुला/बंद सिद्धांत प्रदान करता है, ताकि आप गुंजाइश चर प्रयोग किया जाता है और कहीं और पुन: उपयोग नहीं कर रहा है। अगले लूप पर, परिवर्तक गुंजाइश खो देता है और स्वचालित रूप से पुनः आरंभ किया जाता है।

1

मुझे लगता है कि यह प्रदर्शन के लिए कोई फर्क नहीं पड़ता, लेकिन मैं पहले व्यक्ति को पसंद करता हूं। यदि संभव हो तो मैं हमेशा घोषणा और तत्कालता को एक साथ रखने की कोशिश करता हूं।

+0

'जाने के लिए परिभाषा' बहुत अधिक उपयोगी है जब यह वास्तव में ऑब्जेक्ट को घोषित करने के बजाए सेट करता है। – cjk

3

आप दोनों ही मामलों में प्रत्येक पाश चरण में एक नई वस्तु बना रहे हैं (आप new SomeClass() फोन के बाद से)।

पूर्व दृष्टिकोण यह स्पष्ट करता है कि sc केवल लूप के अंदर उपयोग किया जाता है, जो रखरखाव के दृष्टिकोण से लाभ हो सकता है।

0

मैं पहले का उपयोग करता हूं, लेकिन कंपाइलर के लिए यह वही है, क्योंकि कंपाइलर लूप से चर के घोषणापत्र को बाहर ले जाता है। कोड को संकलित करने के बाद मैं शर्त लगाता हूं कि दूसरे की तरह दिखता है।

+0

बंद करें। दूसरा स्केल करने के लिए शून्य को असाइन करने के लिए 2 अतिरिक्त आईएल कमांड, ldnull और stloc.n पैदा करता है। –

12

सबसे पहले, मुझे लगता है कि आपका मतलब है कि "ऑब्जेक्ट्स बनाना" कहने पर आपका मतलब है "चर" बनाना। ऑब्जेक्ट संदर्भ चर में जाते हैं, लेकिन वे स्वयं चर नहीं हैं।

ध्यान दें कि परिदृश्य में आप का वर्णन एक अर्थ अंतर का परिचय जब पाश एक गुमनाम समारोह में शामिल है और चर गुमनाम समारोह के एक बंद से अधिक बाहरी varible है।

http://ericlippert.com/2009/11/12/closing-over-the-loop-variable-considered-harmful-part-one/

जानकारी के लिए

देखें।

1

मैं सभी घोषणाओं को एक ही स्थान पर रखने के लिए विकल्प 2 के साथ साफ रहूंगा। आप कह सकते हैं कि "ऑब्जेक्ट्स को केवल घोषित किया जाना चाहिए कि उन्हें कहां और कब चाहिए" लेकिन आपका लूप शायद अपनी छोटी विधि में होगा।

+1

एक सी प्रोग्रामर की तरह कहा। – riwalk