2010-01-08 13 views
8

ठीक है, तो यहां सवाल है ... नया कीवर्ड अप्रचलित है?क्या नई चीजें अप्रचलित हैं?

सी # (और जावा, मेरा मानना ​​है) में विचार करें कि प्रकारों के लिए सख्त नियम हैं। कक्षा संदर्भ प्रकार हैं और केवल ढेर पर ही बनाई जा सकती हैं। पीओडी प्रकार ढेर पर बनाए जाते हैं; यदि आप उन्हें ढेर पर आवंटित करना चाहते हैं तो आपको उन्हें ऑब्जेक्ट प्रकार में बॉक्स करना होगा। सी # में, structs अपवाद हैं, वे ढेर या ढेर पर बनाया जा सकता है।

इन नियमों को देखते हुए, क्या यह समझ में आता है कि हमें अभी भी नए कीवर्ड का उपयोग करना है? क्या इस भाषा के आधार पर उचित आवंटन रणनीति का उपयोग करने के लिए भाषा का अर्थ नहीं होगा?

उदाहरण के लिए, हम वर्तमान में लिखने के लिए है:

SomeClassType x = new SomeClassType(); 

SomeClassType x = SomeClassType(); 

या बस

SomeClassType x; 

संकलक के बजाय

होता है, के आधार पर उस प्रकार बनाया जा रहा एक संदर्भ प्रकार है, आगे बढ़ें और ढेर पर एक्स के लिए स्मृति आवंटित करें।

यह रूबी, PHP, et al जैसी अन्य भाषाओं पर लागू होता है। सी/सी ++ प्रोग्रामर को ऑब्जेक्ट्स कहां बनाए जाते हैं, इस पर अधिक नियंत्रण की अनुमति देता है, इसलिए नए कीवर्ड की आवश्यकता के लिए इसका अच्छा कारण है।

new क्या 60 और हमारे सी आधारित विरासत से सिर्फ एक होल्डओवर है?

+0

और यह समुदाय विकी नहीं है क्योंकि ...? –

+0

मुझे नहीं पता। क्या आपको लगता है कि यह होना चाहिए? –

+1

यह एक बिल्कुल मान्य सवाल है। और एक अच्छा भी,। सीडब्ल्यू के लिए कोई ज़रूरत नहीं है। – bsneeze

उत्तर

18
SomeClassType x = SomeClassType(); 
इस मामले SomeClassType() में

कहीं और स्थित एक विधि, कैसे संकलक पता होगा इस पद्धति को कॉल करें या एक नया वर्ग पैदा करने के लिए है कि क्या हो सकता है।

SomeClassType x; 

यह बहुत उपयोगी नहीं है, ज्यादातर लोगों को इस तरह उनके चर घोषित करने और कभी कभी उन्हें बाद पॉप्युलेट जब वे की जरूरत है। इसलिए प्रत्येक बार जब आप एक चर घोषित करते हैं तो स्मृति में एक उदाहरण बनाने के लिए उपयोगी नहीं होगा।

+0

सच है, लेकिन क्या आप इसे शून्य पर सेट करके इसे संबोधित नहीं कर सके? –

+2

@flyfish: अगर आप इसे अपरिवर्तनीय नहीं चाहते थे (यानी।जावा या अन्य भाषाओं के समकक्षों में 'अंतिम'), तब आप बाद में कुछ और असाइन नहीं कर सके। –

+1

यदि वह शून्य हो जाता है तो वह बाद में कैसे निर्माण करेगा? –

5

शुरुआत के लिए:

SomeClassType x; 

आरंभ नहीं किया जाता है, तो कोई स्मृति आवंटित किया जाना चाहिए।

इसके अलावा, आप उन समस्याओं से कैसे बचते हैं जहां कक्षा के समान नाम के साथ कोई विधि है।

आप कुछ कोड लिखने कहते हैं:

int World() { return 3; } 

int hello = World(); 

और सब कुछ अच्छा है और हंसमुख।

अब आप एक नया कक्षा बाद में लिखें:

class World 
{ 
    ... 
} 

अचानक अपने int hello = World() लाइन अस्पष्ट है।

+1

* अचानक आपकी int हैलो = वर्ल्ड() लाइन संदिग्ध है। * यह गतिशील भाषाएं नहीं है (जैसे पायथन) इस परिदृश्य को बहुत अच्छी तरह से संभाल सकता है, एक संकलित भाषा एक त्रुटि फेंकनी चाहिए (जैसे कि जब आप पहले से परिभाषित एक विधि बनाते हैं) – OscarRyz

+0

प्रतिबिंब की शक्ति को देखते हुए, मुझे नहीं लगता कि यह एक मुद्दा है। सी # एक प्रकार और एक प्रकार के उदाहरण के साथ एक ही नाम के साथ अंतर निर्धारित कर सकता है (भले ही यह करने के लिए एक अच्छी बात नहीं है!)। हालांकि इस मामले में संकलक को डायग्नोस्टिक बढ़ाने के लिए आसान होगा –

+0

@Stan, मेरे उदाहरण में वर्ल्ड() केवल एक ऐसा फ़ंक्शन है जो एक int देता है, इसलिए यह पूरी तरह से मान्य है। – tster

0

यदि आपके पास पैरामीटर रहित कन्स्ट्रक्टर नहीं है, तो यह बदसूरत हो सकता है।

यदि आपके पास एकाधिक निर्माता हैं, तो यह वास्तविक बदसूरत हो सकता है।

1

मैं जावा के साथ कई वर्षों से प्रोग्रामिंग कर रहा हूं और मुझे कभी परवाह नहीं है कि मेरी वस्तु ढेर या ढेर पर है या नहीं। उस परिप्रेक्ष्य से new टाइप करने के लिए मेरे जैसा ही है या इसे टाइप न करें।

मुझे लगता है कि यह अन्य भाषाओं के लिए अधिक प्रासंगिक होगा।

मेरी एकमात्र चीज है कि कक्षा में सही संचालन है और मेरी वस्तुएं ठीक से बनाई गई हैं।

Btw, मैं का उपयोग (या कोशिश) केवल कारखाने में new कीवर्ड का उपयोग करने के merthod तो मेरे मुवक्किल वैसे भी इस तरह दिखता है

SomeClasType x = SomeClasType.newInstance(); 

देखें: Effective Java Item:1

+1

जावा ऑब्जेक्ट्स स्टैक पर कभी नहीं होते हैं। – tster

+2

दरअसल, हॉटस्पॉट वीएम एक ऑप्टिमाइज़ेशन के रूप में स्टैक पर ऑब्जेक्ट आवंटित कर सकता है अगर बचने के विश्लेषण के बाद, यह निर्धारित करता है कि यह एक विधि के लिए स्थानीय है। हॉटस्पॉट ऐसी चीजों के साथ बहुत बुद्धिमान है, हालांकि प्रोग्रामर को वास्तव में कभी परवाह नहीं करना चाहिए। –

+1

@ जो एम: हाँ, यही कारण है कि हमें अंतिम चर के रूप में चिह्नित करना है जिसे हम आंतरिक कक्षाओं से एक्सेस करना चाहते हैं। लेकिन यह संकलक नौकरी है। – OscarRyz

16

आपका तीसरी विधि काम नहीं करेगा, चूंकि कभी-कभी हम एक प्रकार की वस्तु को परिभाषित करना चाहते हैं और इसे किसी अन्य प्रकार के चर के लिए असाइन करना चाहते हैं। उदाहरण के लिए:

Stream strm = new NetworkStream(); 

मुझे एक स्ट्रीम प्रकार चाहिए (शायद कहीं पर जाने के लिए), लेकिन आंतरिक रूप से मैं नेटवर्कस्ट्रीम प्रकार चाहता हूं।

इसके अलावा कई बार मैं एक विधि बुला जबकि एक नई वस्तु बनाने:

myobj.Foo(new NetworkStream()); 

इस तरह से कर रही:

myobj.Foo(NetworkStream()); 

बहुत भ्रामक है। क्या मैं एक ऑब्जेक्ट बना रहा हूं, या जब मैं नेटवर्कस्ट्रीम() कहता हूं तो एक विधि को कॉल कर रहा हूं?

+0

अच्छा बिंदु। मैं यहां सभी उपयोग मामलों को कवर करने का प्रयास नहीं कर रहा था। बस एक सामान्य सवाल है। –

+0

इसका उद्देश्य क्या है? बस 'नेटवर्कस्ट्रीम strm = new networkStream(); ' – tster

+0

हाँ, स्ट्रीम strm = new networkStream() एक खराब उदाहरण है ... यह शायद एक बेहतर है: स्ट्रीम [] स्ट्रीम = नया स्ट्रीम [2]; स्ट्रीम [0] = नया नेटवर्कस्ट्रीम(); स्ट्रीम [1] = नया फ़ाइलस्ट्रीम(); क्रैपी स्वरूपण के लिए खेद है, मैं यह नहीं समझ सकता कि इस टिप्पणी बॉक्स में कोड प्रारूप कैसे करें। –

3

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

6

यदि आप केवल SomeClassType x; लिख सकते हैं और इसे स्वचालित रूप से प्रारंभ किया है, तो यह किसी भी पैरामीटर के साथ रचनाकारों की अनुमति नहीं देगा। प्रत्येक SomeClassType में पैरामीटर रहित कन्स्ट्रक्टर नहीं होगा; संकलक को कैसे पता चलेगा कि तर्क क्या है?

public class Repository 
{ 
    private IDbConnection connection; 

    public Repository(IDbConnection connection) 
    { 
     if (connection == null) 
     { 
      throw new ArgumentNullException("connection"); 
     } 
     this.connection = connection; 
    } 
} 

कैसे तुम सिर्फ Repository rep; के साथ इस वस्तु का दृष्टांत हैं? यह एक निर्भर वस्तु को ठीक से काम करने की आवश्यकता है।

नहीं उल्लेख करने के लिए, तुम इतनी तरह कोड लिखने के लिए चाहते हो सकता है:

Dictionary<int, SomeClass> instances = GetInstancesFromSomewhere(); 
SomeClass instance; 
if (instances.TryGetValue(1, out instance)) 
{ 
    // Do something 
} 

तुम सच में आप के लिए यह स्वत: आरंभ चाहते हैं?

यदि आपने अभी SomeClassType x = SomeClassType() लिखा है तो यह किसी कन्स्ट्रक्टर और दायरे में एक विधि के बीच कोई भेद नहीं करता है।

अधिक आम तौर पर:

मुझे लगता है कि क्या new कीवर्ड के लिए है की एक बुनियादी गलतफहमी है।तथ्य यह है कि स्टैक पर मूल्य प्रकार आवंटित किए जाते हैं और ढेर पर आवंटित "संदर्भ" प्रकार कार्यान्वयन विवरण है। new कीवर्ड विनिर्देश का हिस्सा है। एक प्रोग्रामर के रूप में, आपको परवाह नहीं है कि यह ढेर या ढेर (अधिकांश समय) पर आवंटित है या नहीं, लेकिन आपको निर्दिष्ट करने की आवश्यकता है कि ऑब्जेक्ट को कैसे प्रारंभ किया गया है।

वहाँ अन्य वैध जैसे भी initializers के प्रकार, कर रहे हैं:

int[] values = { 1, 2, 3, 4 }; 

Voilà, कोई new के साथ एक प्रारंभ। इस मामले में संकलक आपके लिए इसे समझने के लिए पर्याप्त स्मार्ट था क्योंकि आपने एक शाब्दिक अभिव्यक्ति प्रदान की जो पूरे ऑब्जेक्ट को परिभाषित करता है।

तो मुझे लगता है कि मेरा "उत्तर" है, इस बारे में चिंता न करें कि वस्तु स्मृति-वार कहां मौजूद है; new कीवर्ड का उद्देश्य, ऑब्जेक्ट प्रारंभकर्ता के रूप में प्रारंभ करने की आवश्यकता वाले ऑब्जेक्ट्स के लिए करें।

2

यह मतलब नहीं होगा भाषा प्रकार के आधार पर उचित आवंटन रणनीति का उपयोग करने के लिए?

यह वही है जो सी # कंपाइलर/रनटाइम पहले से ही करता है। new कीवर्ड किसी ऑब्जेक्ट को बनाने के लिए सिंटैक्स है जो उस ऑब्जेक्ट के लिए किसी भी तरह से समझ में आता है।

new कीवर्ड को हटाने से यह कम स्पष्ट हो जाएगा कि एक निर्माता को बुलाया जा रहा है।

myDictionary.TryGetValue(key, out val); 

संकलक पहले से ही जानता है कि val एक out है: एक ऐसी ही उदाहरण के लिए, out मापदंडों पर विचार करें। यदि आप ऐसा नहीं कहते हैं, तो यह शिकायत करता है। लेकिन यह कोड को यह कहने के लिए और अधिक पठनीय बनाता है।

कम से कम, यह औचित्य है - आधुनिक आईडीई में इन चीजों को वास्तविक डालने वाले पाठ के अलावा अन्य तरीकों से पाया जा सकता है और हाइलाइट किया जा सकता है।

क्या नया 60 के और हमारी सी आधारित विरासत से होल्डओवर है?

निश्चित रूप से नहीं। सी में new कीवर्ड नहीं है।

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