2010-10-27 15 views
52

नीचे कोड, किस तरह से position0 आरंभ नहीं हो जाता है और जिस तरह position1 के बीच का अंतर आरंभ नहीं हो जाता है को देखते हुए? क्या वे बराबर हैं? यदि नहीं, तो क्या अंतर है?सी # नया बयान के बाद ब्रेसिज़ क्या करते हैं?

class Program 
{ 
    static void Main(string[] args) 
    { 
     Position position0 = new Position() { x=3, y=4 }; 

     Position position1 = new Position(); 
     position1.x = 3; 
     position1.y = 4; 
    } 
} 

struct Position 
{ 
    public int x, y; 
} 

उत्तर

41

वस्तु और संग्रह initializers, एक वस्तु पर खेतों प्रारंभ करने में इस्तेमाल किया।

http://msdn.microsoft.com/en-us/library/bb384062.aspx

वे लगभग बराबर आईएल का उत्पादन। जॉन स्कीट का जवाब है कि वास्तव में क्या चल रहा है।

+1

उसमें बहुत सच्चाई। मेरा जवाब पोस्ट किया ... उसका जवाब देखा, इसे अपने जवाब को इंगित करने के लिए संपादित किया। –

+0

जॉन स्कीट इस साइट पर हर प्रश्न का उत्तर देने लगता है :) मैं अपनी नई पुस्तक पढ़ने के लिए इंतजार नहीं कर सकता (अगर यह वास्तव में रिलीज़ हो जाता है) – Bryan

1

ये पूरी तरह से समकक्ष हैं। संकलक वास्तव में पहले संस्करण को दूसरे संस्करण में बदल देता है। दूसरा प्रारंभ से कोड का एक बहुत अधिक लाइनों

DoSomethingWithPoint(new Position() { x=3, y=4 }); 

यह वह जगह है:

दोनों के बीच फर्क सिर्फ इतना है कि पहले के साथ, आप अच्छा thins कर सकते हैं, जैसे एक विधि के लिए शुरू संस्करण पारित है उदाहरण।

2

आपका दो कोड नमूने समान आईएल उत्पन्न होगा। (कम से कम रिलीज में बनाता है)

5

यह एक ऑब्जेक्ट प्रारंभकर्ता है, और बस आपको एक अभिव्यक्ति में मान असाइन करने की अनुमति देता है। सबसे महत्वपूर्ण बात, यह भी गुमनाम प्रकार के लिए LINQ एक (अन्यथा अपरिवर्तनीय) के अंदर काम करता है। नए संग्रह में एडीआई आइटम्स के लिए एक समान संग्रह प्रारंभिक वाक्यविन्यास भी है।

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

+0

यहोशू और स्लैक्स ने पोस्ट किया कि 'स्थिति' शुरू करने के दोनों तरीके बराबर आईएल उत्पन्न करते हैं। क्या आप कह रहे हैं कि अज्ञात प्रकार के साथ, मुझे एक अलग परिणाम मिलेगा? –

+0

@rice - हाँ: उनमें से केवल एक संकलित होगा :) –

1

वे समकक्ष हैं, एक दूसरे के मुकाबले पढ़ने में आसान है।

इसके अलावा मामले पर विचार के लिए जब आप कहीं और करने के लिए साथ-साथ नई वस्तु पास करना चाहते हैं:

var aList = new List<Position>(); 
aList.Add(new Position() { x=3, y=4 }); 
51

वे काफी समान नहीं होते हैं - कम से कम नहीं सामान्य स्थिति में। एक ऑब्जेक्ट प्रारंभकर्ता का उपयोग कर कोड इस के करीब है:

Position tmp = new Position(); 
tmp.x = 3; 
tmp.y = 4; 
Position position1 = tmp; 

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

Position p1 = new Position { x = 10, y = 20 }; 

p1 = new Position { x = p1.y, y = p1.x }; 

हैं कि p1पहले लिए काम किया है, आप p1.x और p1.y दोनों के लिए 0 को रखना होगा। जबकि यह वास्तव में बराबर है:

Position tmp = new Position(); 
tmp.x = 10; 
tmp.y = 20; 
Position p1 = tmp; 

tmp = new Position(); 
tmp.x = p1.y; // 20 
tmp.y = p1.x; // 10 
p1 = tmp; 

संपादित करें: मुझे अभी एहसास हुआ है कि आप कक्षा के बजाय एक संरचना का उपयोग कर रहे हैं।इससे कुछ सूक्ष्म मतभेद हो सकते हैं ... लेकिन आप लगभग निश्चित रूप से एक म्यूटेबल स्ट्रक्चर का उपयोग नहीं करना चाहिए :)

2

सभी आईएल सामानों को भूलना, यह सिर्फ शॉर्टेंड नोटेशन है। आप क्या कर रहे हैं यह है:

ए। एक मामले में आप स्पष्ट रूप से डिफ़ॉल्ट कन्स्ट्रक्टर का उपयोग कर रहे हैं और फिर दो गुणों को सेट कर रहे हैं।

बी। दूसरी तरफ, आप नए इंटियालाइज़र सिंटैक्स का उपयोग कर रहे हैं जो कि संकलक को पूरी तरह से करता है जो आपने किया था।

आईएल subtelties के बावजूद, वे आपके लिए एक ही चीज़ प्राप्त करेंगे।

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