2011-09-04 15 views
7
namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      object[] obj = new object[3]; 
      obj[0] = new object(); 
      obj[1] = "some string"; 
      obj[2] = 10; 

      string[] strings = new string[] { "one", "two", "three" }; 
      obj = strings; //---> No Error here, Why ? 

      int[] ints = new int[] { 1, 2, 3 }; 
      obj = ints; /*-> Compiler error - Cannot implicitly convert type 'int[]' to 'object[]', Why ?*/ 
     } 
    } 
} 

मुझे ऊपर दिखाए गए चरण को करने के दौरान एक कंपाइलर त्रुटि मिलती है। लेकिन, पिछले चरण में, कोई त्रुटि नहीं है। क्या कोई मुझे इस व्यवहार की व्याख्या कर सकता है? मैं वीएस 2010 का उपयोग कर रहा हूं।सी # - कंपाइलर त्रुटि - ऑब्जेक्ट को int [] असाइन करने के दौरान []

संपादित करें - पूर्णता के लिए, फिर से, यह संकलित नहीं होगा - .NET 4.0 में भिन्न समर्थन अब साफ़ कर दिया गया है। कोई भी सामान्य कीवर्ड पैरामीटर के साथ और में नए कीवर्ड का उपयोग कर सकता है।

List<object> objectList = new List<object>(); 
    List<string> stringList = new List<string>(); 
    objectList = stringList; 
+2

आप के बीच मतभेदों को समझते हो मूल्य प्रकार और संदर्भ प्रकार? – Oded

उत्तर

6

संदर्भ प्रकार के केवल सरणियों (जैसे String) अन्य संदर्भ प्रकार के सरणियों (जैसे Object) को आबंटित हो सकता है। चूंकि int एक मान प्रकार है, इसलिए इसके सरणी अन्य प्रकार के सरणी को असाइन नहीं किए जा सकते हैं।

अधिक विशिष्ट होने के लिए, इसे array covariance कहा जाता है। यह केवल तब काम करता है जब सरणी में संग्रहीत बिट पैटर्न गंतव्य प्रकार के साथ संगत होते हैं। उदाहरण के लिए, String[] में बिट्स तारों के सभी संदर्भ हैं और ऑब्जेक्ट्स के संदर्भ संग्रहीत स्मृति स्थानों में सुरक्षित रूप से कॉपी किए जा सकते हैं। मूल्य प्रकारों की एक सरणी, हालांकि, तत्वों के वास्तविक डेटा को संग्रहीत करती है (जैसा कि उनके संदर्भ में है)। इसका मतलब है कि int[] सरणी के तत्वों में वास्तविक 32-बिट पूर्णांक संग्रहीत करता है। चूंकि किसी 32-बिट पूर्णांक को किसी ऑब्जेक्ट या किसी अन्य प्रकार के संदर्भ को संग्रहीत करने वाले स्मृति स्थान में सुरक्षित रूप से कॉपी नहीं किया जा सकता है, इसलिए आप किसी अन्य प्रकार की सरणी में उन्हें एक सरणी निर्दिष्ट नहीं कर सकते हैं।

ध्यान दें कि तकनीकी रूप से int की बिट्स को uint (और इसके विपरीत) संग्रहीत स्मृति स्थान में सुरक्षित रूप से कॉपी किया जा सकता है। इसका मतलब है कि आपको int[] x = new uint[10] जैसे कुछ करने में सक्षम होना चाहिए। यह वास्तव में covariance नहीं है और सी # इसे अनुमति नहीं देता है। हालांकि, यह सीएलआर में कानूनी है और यदि आप चाहें तो आप इसे करने के लिए सी # को मनाने के लिए मना सकते हैं।

+0

लेकिन सब कुछ अंततः system.object –

+0

धन्यवाद गेबे। ऐरे covariance कुंजी है! –

1

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

2

string और object दोनों संदर्भ प्रकार हैं। यही है, उन प्रकारों का एक चर वास्तव में स्मृति में कहीं और सूचक को संग्रहीत करता है। int एक मूल्य प्रकार है। यही है, डेटा सीधे संग्रहीत किया जाता है जहां चर घोषित किया जाता है।

इसका मतलब है कि संदर्भ प्रकारों की एक सरणी मूल प्रकार की सरणी के लिए मूल रूप से अलग है। संदर्भ प्रकारों की एक सरणी पॉइंटर्स की सरणी के रूप में संग्रहीत की जाती है। चूंकि पॉइंटर्स सभी एक ही आकार के होते हैं, इसका मतलब है कि string[] को object[] सिम्पी के रूप में दोबारा समझने का मतलब है सरणी में वस्तुओं तक पहुंचने के दौरान किए गए प्रकार की जांच को समायोजित करना (मोटे तौर पर बोलना)।

हालांकि, int[] में, मान सीधे सरणी में संग्रहीत होते हैं; int मान एक साथ संयोजित हैं। कोई संकेतक शामिल नहीं हैं। इसका अर्थ यह है कि int[] को object[] के रूप में दोबारा समझने के लिए सरणी में किसी ऑब्जेक्ट में संग्रहीत प्रत्येक मान बॉक्सिंग की आवश्यकता होती है। इसलिए आप एक साधारण कास्ट या असाइनमेंट का उपयोग करके ऐसा क्यों नहीं कर सकते - यह एक ओ (एन) ऑपरेशन है जो एक नई सरणी बनाता है। इसके बजाय, आप Array.Copy का उपयोग कर सकते हैं जो आपके लिए सभी मुक्केबाजी से संबंधित है।

0

यदि आपके पास विजुअल स्टूडियो इंस्टॉलेशन है तो आपको सी # भाषा स्पीसिफिकेशन को वीसी # के तहत कहीं भी दस्तावेज़ फ़ाइल के रूप में मिलेगा। अध्याय 12।सहप्रसरण के साथ 5 सौदों और वहाँ यह कहते

किसी भी दो संदर्भ-टाइप ए और बी के लिए, एक अंतर्निहित संदर्भ रूपांतरण (§6.1.6) या स्पष्ट संदर्भ रूपांतरण (§6.2.4) एक से मौजूद रहने पर बी के लिए, फिर एक ही संदर्भ रूपांतरण सरणी प्रकार ए [आर] से सरणी प्रकार बी [आर] तक मौजूद है, जहां आर रैंक-विनिर्देशक (लेकिन दोनों सरणी प्रकारों के लिए समान है) है। यह संबंध को सरणी कोविरिएंस के रूप में जाना जाता है।

यह आपके प्रश्न का उत्तर नहीं दे सकता है, लेकिन यह इस तरह से ऐसा करने के लिए एक जानबूझकर निर्णय था।

1

यह क्यों काम नहीं कर रहा है यहां कई उत्तरों में बताया गया है, इसलिए मैं जो भी कहता हूं उसे प्रतिलिपि बनाने की कोशिश नहीं करूंगा।

आप, या किसी और वास्तव में ऐसा करना चाहते हैं किसी कारण से (int[]object[] में कनवर्ट करें), तुम इतनी तरह LINQ का उपयोग कर सकते हैं:

int[] ints = new int[] { 1, 2, 3 }; 
object[] obj_ints = (from i in ints select i).Cast<object>().ToArray(); 

;)

+0

कई कामकाज हो सकते हैं। कृपया –

+1

से नीचे 'गेबे' का उत्तर देखें, क्यों न केवल 'Array.Copy' का उपयोग करें? http://msdn.microsoft.com/en-us/library/system.array.copy.aspx – Gabe

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