2013-02-20 13 views
7

इतने पर एक और सवाल पर चर्चा करते हैं, मुझे बताया गया था कि वाक्य रचनाएक सरणी प्रकार की घोषणा

int[] numbers = new int[10]; 

की तुलना में बेहतर

Array numbers = Array.CreateInstance(typeof(int), 10); 

मेरा प्रश्न है, जब पहली वाक्य रचना उपयोगी है और जब है दूसरा वाक्यविन्यास उपयोगी है? और क्यों?

+0

वे पूरी तरह से अलग चीजें करते हैं। – asawyer

+6

जब आप संकलन समय पर प्रकार जानते हैं, तो मैं दूसरे फॉर्म का उपयोग करने के लिए * कोई * लाभ नहीं देख सकता। –

+1

अधिकांश कक्षाओं के विपरीत, Array सार्वजनिक निर्माणकर्ताओं की बजाय CreateInstance विधि प्रदान करता है, ** देर से बाध्य पहुंच ** की अनुमति देने के लिए। - [Array.CreateInstance विधि] (http://msdn.microsoft.com/en-us/library/zb3cfh7k.aspx) – Habib

उत्तर

6

यह एक जोरदार टाइप किया monodimensional सरणी "सीधे" बनाता है।

यह एक और एक सरणी बनाने के लिए प्रतिबिंब का उपयोग करने के लिए इसी तरह की (प्रकार रनटाइम पर फैसला किया जा सकता है)

int[] array2 = (int[])Array.CreateInstance(typeof(int), 10); 

सरणी अंत में बनाए गए एक ही है, लेकिन यह बनाने की गति बहुत धीमी है है Array.CreateInstance का उपयोग करते समय।ध्यान दें कि Array.CreateInstance के साथ गतिशील सरणी के प्रकार (एक ही तरीका है कि प्रतिबिंब के माध्यम से आप एक प्रकार कार्यावधि में प्रकार दिया का एक उदाहरण बना सकते हैं) का चयन कर सकते हैं, उदाहरण के लिए:

Type type = someCondition ? typeof(int) : typeof(string); 
Array array2 = Array.CreateInstance(type, 10); 

एक और बड़ा अंतर: "आधार" Array वर्ग कमजोर टाइप किया गया है (इसलिए इसकी विधियां object पैरामीटर का उपयोग करती हैं, int/string '/ something) के बजाय। तो:

int num = (int)array2.GetValue(1); // You have to cast the return value to int from object 

एक अन्य कारण

array[5] = 1; 

बजाय

array2.SetValue(5, 1); 

की जाती है कि पहली विधि एक monodimensional करने के लिए एक सीधी पहुँच के रूप में आईएल कोड में अनुकूलित है उपयोग करने के लिए सरणी (stelem और ldelem)। GetValue के लिए भी यही सच है।


कारण मैं शब्द "monodimensional सरणी" उपयोग कर रहा हूँ:

नेट में दो सरणियों के "प्रकार" देखते हैं: monodimensional सरणियों और "जटिल" सरणियों (वे बहुआयामी हो सकता है , या पहले तत्व के साथ 0 सूचकांक, या दोनों पर नहीं)। दूसरा समूह बहुत धीमा है। stelem और ldelem केवल monodimensional arrays के साथ काम करते हैं। बहुआयामी/विशेष सरणी के लिए "छिपा" विधियों का उपयोग उन तक पहुंचने के लिए किया जाता है (सी # कंपाइलर प्राप्त करता है और सेट करता है ताकि इन विधियों को बुलाया जा सके) (वे GetValue/SetValueArray कक्षा के समान हैं, उदाहरण के लिए https://stackoverflow.com/a/597729/613130)

+0

धन्यवाद, यह मेरी क्वेरी का उत्तर देता है और आईएल कोड में अंतर्दृष्टि भी देता है। यह ठीक वही है जिसकी मुझे तलाश थी। स्वीकार किए जाते हैं! – TheSilverBullet

5

संकलन समय पर, ऐसा लगता है कि उनके बीच कोई बड़ा अंतर नहीं है। सरणी की तरह, Array.CreateInstance विधि भी संदर्भ-प्रकार तत्वों को null पर प्रारंभ किया गया है। मूल्य-प्रकार तत्व zero पर प्रारंभ किए गए हैं।

enter image description here

दूसरे के लिए केवल अंतर है; MSDN से;

अधिकांश वर्गों के विपरीत, सरणी CreateInstance विधि, बजाय सार्वजनिक निर्माताओं की , देर से बाध्य पहुँच के लिए अनुमति देने के लिए प्रदान करता है।

इसके अलावा Stefano Altieri mentioned के रूप में, पहले वाक्य रचना संकलन समय में सरणी आकार आवश्यकता है, लेकिन एक दूसरे के रन-टाइम में आकार की जरूरत है। उदाहरण के लिए, आप इन कोडों को सफलतापूर्वक बना सकते हैं;

int[] numbers1 = new int[10]; 
Array numbers2 = Array.CreateInstance(typeof(int), -1); 

लेकिन आप इन्हें नहीं बना सकते हैं;

int[] numbers1 = new int[]; 
Array numbers2 = Array.CreateInstance(typeof(int), -1); 
+1

मुझे यकीन नहीं है कि मैं कहूंगा कि" कोई अंतर नहीं है "एक अभिव्यक्ति के बीच जो 'int [10]' और एक अभिव्यक्ति जो' ऐरे 'देता है। – asawyer

+1

उपरोक्त। एक असली परीक्षण अच्छा है। –

+1

दृश्य के लिए धन्यवाद। ये उपयोगी है। यदि आप "टाइप" कॉलम चेक करते हैं, तो आप देखेंगे कि दो घोषणाएं वास्तव में अलग हैं। – TheSilverBullet

4

आपके द्वारा लिखे गए नमून समकक्ष हैं। मुद्दा यह है कि पहले वाक्यविन्यास (नया int [आकार]) का उपयोग करने के लिए आपको संकलन समय पर सरणी प्रकार को जानने की आवश्यकता है।

दूसरा वाक्यविन्यास आपको रनटाइम पर सरणी वस्तुओं के प्रकार पर निर्णय लेने की अनुमति देता है। यह कहीं अधिक शक्तिशाली है, लेकिन आपको हमेशा इस शक्ति की आवश्यकता नहीं है। अर्थात। हुड यह आईएल आदेश newarr का उपयोग करता है के तहत

int[] array = new int[10]; 

:

Type myType = SelectTheBestType(); 
var numbers = Array.CreateInstance(myType, 10); 
2

Soner Gönül का उत्तर बहुत अच्छा है। आपके प्रश्न का एक साधारण कारण

यदि कोई सरणी ऑब्जेक्ट या इंटरफ़ेस के रूप में पास की जाती है, तो तत्व प्रकार संकलन समय पर अज्ञात है।

[This answer] क्या आप विचार लाने सकता है, और [here] उदाहरण के लिए कुछ कोड है।

पहला वाक्यविन्यास उपयोगी कब होता है और दूसरा वाक्यविन्यास उपयोगी कब होता है?

उदाहरण के लिंक में विधि,

static IList CreateArray<T>(this T source); 

सामान्य प्रकार पैरामीटर T बजाय T[] है की वजह से मुझे लगता है कि नहीं कर सकता कि sourceजरूरी एक सरणी किया गया, लेकिन यह अभी भी संभवतः । इस प्रकार मैं विधि के अंदर केवल Array.CreateInstance का उपयोग कर सकता हूं।

अधिकांश समय, यदि तत्व प्रकार संकलित समय पर पहले ही ज्ञात है, तो भाषा द्वारा प्रदान किए गए वाक्यविन्यास का उपयोग करना बेहतर है।