2012-05-13 20 views
8

सदस्य घोषणा में new और एक निर्माता में new के बीच क्या अंतर है?सदस्य घोषणा में नए और कन्स्ट्रक्टर में नए के बीच क्या अंतर है?

उदाहरण

public class PspGame { 

    private List<string>name = new List<string>(); 
    private List<string>_value; 

    public PspGame() { 
    _value = new List<string>(); 
    } 
} 

यह करते हैं और वहाँ किसी भी प्रदर्शन के मुद्दों कर रहे हैं के लिए सबसे अच्छा तरीका क्या है?

उत्तर

4

मेरे लिए कन्स्ट्रक्टर (गैर-डिफ़ॉल्ट कन्स्ट्रक्टर) में तर्क होने के कारण, बेहतर परीक्षण की अनुमति देता है। आप किसी सदस्य फ़ील्ड में कुछ डेटा इंजेक्ट कर सकते हैं कि आप उस सदस्य को सार्वजनिक (या कम से कम आंतरिक) बनाने या 'सेटर' संपत्ति के साथ दूसरी कॉल करने के बिना आवश्यक रूप से करने में सक्षम नहीं होंगे।

क्योंकि आपके पास एकाधिक कन्स्ट्रक्टर हो सकते हैं, यदि आप वास्तव में चाहते थे तो डिफ़ॉल्ट डिज़ाइनर के संयोजन के साथ परीक्षण के लिए दूसरा स्थान हो सकता है।

बाद में डेटा को पॉप्युलेट करने के लिए अलग कॉल करने के अलावा कोई भी वास्तविक प्रदर्शन समस्या नहीं है, या कक्षा में एकाधिक कॉल के साथ कम-रखरखाव कोड नहीं है (ऑब्जेक्ट बनाने के लिए, सदस्य को पॉप्युलेट करने वाला दूसरा)।

संपादित करें: मुझे एहसास हुआ कि मैंने सॉर्टा ने गलत प्रश्न का उत्तर दिया। मैंने सोचा कि वह डिफ़ॉल्ट और गैर-डिफ़ॉल्ट कन्स्ट्रक्टर के बीच अंतर के बारे में पूछ रहा था। अब मुझे लगता है कि यह एक डिफ़ॉल्ट कन्स्ट्रक्टर के बारे में था जो सदस्य घोषणा में निर्माता बनाम बनाम सदस्य को शुरू करता है ...

+0

ठीक है, प्रदर्शन और स्मृति आवंटन के बारे में कैसे? – retide

+1

यह वास्तव में समझ में नहीं आता है। यदि आप इसे एक कन्स्ट्रक्टर के रूप में पेश नहीं करते हैं, तो आप कुछ इंजेक्ट नहीं कर सकते हैं, और परीक्षण के लिए एक विशिष्ट कन्स्ट्रक्टर कोड गंध है (यह बहुत अधिक प्रत्यक्ष निर्भरताओं वाली कक्षा को इंगित करता है)। यदि आप वास्तव में कक्षा को रद्द करना चाहते हैं, तो उन सभी पैरामीटर को लें जिन्हें इंटरफेस के रूप में बदला जा सकता है। – Femaref

+0

शायद, लेकिन इस सदस्य चर के साथ अपने प्रश्न के संदर्भ में, यह निश्चित रूप से एक विकल्प है। मैं सहमत हूं, इस मामले में जहां आपके पास कई गुण हो सकते हैं, एक इंटरफ़ेस बनाएं और इसे – Killnine

1

दोनों बराबर हैं। कंपाइलर ऐसे किसी भी सदस्य को कन्स्ट्रक्टर (प्रारंभिक कन्स्ट्रक्टर यदि सदस्य स्थिर है) के प्रारंभिक स्थान पर ले जाता है। मैं नहीं कहूंगा कि ऐसा करने का एक सामान्य सबसे अच्छा तरीका है - जहां संभव हो वहां सुसंगत रहें, और यदि कोई स्थिति में अधिक समझ में आता है, तो इसका इस्तेमाल करें।

1

कन्स्ट्रक्टर में इंस्टेंस सदस्यों को आरंभ करें, घोषणा में कक्षा के सदस्यों को आरंभ करें। AFAIK यह (केवल) सम्मेलन है, और कोई प्रदर्शन जुर्माना नहीं है। आईएमएचओ इसे भाषा नियम (वाक्यविन्यास/अर्थात्) में मजबूर होना चाहिए।

10

वे काफी समकक्ष हैं (प्रदर्शन और स्मृति उपयोग के मामले में कोई अंतर नगण्य हैं)।

private List<string>name = new List<string>(); 

... काम हमेशा कोई बात नहीं क्या निर्माता वस्तु का एक उदाहरण बनाने के लिए प्रयोग किया जाता है होता है: केवल वास्तविक अंतर है कि जब आप क्या करते हैं। जब आप किसी कन्स्ट्रक्टर के भीतर असाइनमेंट करते हैं, तो यह तब होता है जब उस विशिष्ट कन्स्ट्रक्टर का उपयोग किया जाता है।

तो यदि आपके पास एकाधिक निर्माता हैं लेकिन आप हमेशा name को उसी तरह से प्रारंभ करना चाहते हैं, तो यह प्रत्येक कन्स्ट्रक्टर में इसे स्पष्ट रूप से प्रारंभ करने के बजाय पहले फ़ॉर्म का उपयोग करने के लिए थोड़ा छोटा है।

एक सामान्य नियम के रूप में, हालांकि, मैं कन्स्ट्रक्टर कार्यान्वयन में फ़ील्ड प्रारंभ करना पसंद करता हूं, भले ही यह कुछ मामलों में कोड को अधिक वर्बोज़ बनाता है।

class MyClass 
{ 
    private List<string> _list = new List<string>(); 
    public MyClass() 
    { 
     //some logic here 
    } 
    public MyClass(List<string> initialList) : this() 
    { 
     _list = initialList; 
    } 
} 

इस कोड के साथ, अगर आप दूसरे निर्माता कहते हैं, आप बेकार में एक सूची है कि लगभग तुरंत छोड़ दिया और के लिए पात्र बना दिया पैदा करेगा: निर्माता में

+0

एक साइड नोट के रूप में, कंपाइलर वास्तव में सभी रचनाकारों को किसी भी सदस्य प्रारंभिक कोड को स्थानांतरित करता है। इसका मतलब यह है कि इसे बिल्कुल कन्स्ट्रक्टर में डालने से बिल्कुल कोई प्रदर्शन/मेमोरी उपयोग आवश्यकता मतभेद नहीं होना चाहिए, सिवाय इसके कि प्रत्येक कन्स्ट्रक्टर के उपयोग के लिए निर्देश दोहराए जाएंगे (यह केवल तभी महत्वपूर्ण होगा जब आपके पास उदाहरण सदस्यों के लिए प्रारंभिक निर्देशों के मेगाबाइट्स के लायक हों इस तरह घोषित किया, और कई रचनाकारों)। –

+0

यह एक बहुत अच्छा स्पष्टीकरण है, और वास्तव में प्रश्न का उत्तर देता है;) +1 – Killnine

+0

@TimS। क्या आपके पास इस बात का बैक अप लेने का कोई सबूत है कि फील्ड प्रारंभकर्ता कन्स्ट्रक्टर में स्थानांतरित हो जाते हैं? यह मेरे लिए बहुत ही असंभव प्रतीत होता है, क्योंकि [क्षेत्र प्रारंभकर्ताओं और आधार वर्गों के रचनाकारों को एक ही क्रम में नहीं कहा जाता है] (http://blogs.msdn.com/b/ericlippert/archive/2008/02/15/why-do -initializers रन-इन-द-विपरीत-क्रम के रूप में कंस्ट्रक्टर्स-पार्ट-one.aspx)। फील्ड प्रारंभकर्ता बेस क्लास के फील्ड प्रारंभकर्ताओं से पहले * और उसके कन्स्ट्रक्टर से पहले चलता है; कन्स्ट्रक्टर * बेस क्लास कन्स्ट्रक्टर के बाद * चलाता है। – phoog

1

शुरु कर रहा है क्षेत्रों में भी आप इस समस्या से बचने के लिए अनुमति देता कचरा इकठा करना।

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