2012-04-13 12 views
8

मेरे पास एक ऐसा क्षेत्र है जो 'ऑब्जेक्ट' प्रकार का है। जब मैं दृश्य स्टूडियो की वॉच विंडो में इसका निरीक्षण करता हूं तो मैं उसका ऑब्जेक्ट देखता हूं [] और जब मैं तत्वों में ड्रिल करता हूं तो मुझे लगता है कि प्रत्येक तत्व एक स्ट्रिंग है।स्ट्रिंग [] के लिए मैं ऑब्जेक्ट (जो वास्तव में ऑब्जेक्ट []) को परिवर्तित नहीं कर सकता?

लेकिन जब मैं एक String [] को यह कास्ट करने के लिए कोशिश मैं इस त्रुटि मिलती है:

Cannot cast 'MyObject' (which has an actual type of 'object[]') to 'string[]' string[]

किसी भी कारण है कि मैं इस डाली ऐसा नहीं कर सकते? इस ऑब्जेक्ट को स्ट्रिंग सरणी में बदलने का सबसे अच्छा तरीका क्या है?

+0

आप अपनी सरणी कास्टिंग कैसे कर रहे हैं? एक पूरे के रूप में? आपको व्यक्तिगत रूप से अपने सरणी के प्रत्येक तत्व को कास्ट करने की आवश्यकता है। – Msonic

+0

हां, वह स्पष्ट रूप से इसे पूरी तरह से कास्टिंग कर रहा है। –

+1

ऐरे-ऑफ-रेफरेंस भिन्नता दूसरी तरफ है; आप ** ऑब्जेक्ट [] 'के रूप में ** वास्तव में ** एक' स्ट्रिंग [] 'कुछ ऐसा कर सकते हैं, लेकिन दूसरी तरफ जाने के लिए यह वास्तव में' स्ट्रिंग [] ' –

उत्तर

16
string[] newarr = Array.ConvertAll(objects, s => (string)s); 

--EDIT--

जब से तुम कहा है मैं एक object है (जानते हुए भी कि यह एक object[] वास्तव में है)

string[] newarr = Array.ConvertAll((object[])objects, s => (string)s); 
+0

होना चाहिए, यह संकलित प्रतीत नहीं होता है। । मुझे त्रुटि मिल रही है: टाइप अनुमान अनुमानित नहीं किया जा सकता है। । । – leora

+0

@leora अद्यतन उत्तर देखें। –

-1

आप परिवर्तित कर सकते हैं असलीstring[] से object[]

यह एक Array covariance

है लिंक में एक स्पष्ट उदाहरण मिल सकता है।

+0

@downvoter: समझाने की देखभाल? – Tigran

+0

मेरे डी/वी नहीं, लेकिन शायद बी/सी में आपने उदाहरण –

0
object[] original = new object[]{"1", "2"}; 
//some code in between here 
object obj = original ; 
object[] objArray = (object[])obj; 
string[] newArray = new string[objArray.Length]; 
for(int i = 0; i < newArray; i++) 
{ 
    newArray[i] = (string)objArray[i]; 
} 

अन्य उत्तर यहां आपको रूपांतरण करने के त्वरित/छोटे तरीके दिखा रहे हैं। मैंने पूरी चीज इस तरह लिखी क्योंकि यह दिखाता है कि वास्तव में क्या चल रहा है और क्या होने की आवश्यकता है। आपको अपने वास्तविक उत्पादन कोड में सरल तरीकों में से एक का उपयोग करना चाहिए।

+0

हम्म शामिल नहीं किया था। । किसी कारण से आपका समाधान केवल एक ही है जो मेरे लिए संकलित करता है और काम करता है। । – leora

+0

@leora अधिकांश लोगों ने समस्या का एक हिस्सा हल किया, लेकिन पूरी बात नहीं। उन्होंने उस हिस्से को अधिक साफ/सुंदर ढंग से हल किया। जैसा कि मैंने कहा था, यह कोड आपको यह दिखाने के लिए डिज़ाइन किया गया है कि क्या होने की आवश्यकता है, भले ही लाइब्रेरी विधि हो, जो आपके लिए आधा है। – Servy

+0

@ सर्वी 'लेकिन पूरी बात नहीं' क्या आप निश्चित हैं? –

-1

आपको प्रत्येक तत्व संग्रह में डालना चाहिए, न कि संग्रह स्वयं।

object[] ovalues = new object[] { "alpha", "beta" }; 
string[] svalues = ovalues.Cast<string>().ToArray(); 
+0

मेरे पास ऑब्जेक्ट नहीं है []। .i केवल वस्तु है। । यह देखते हुए कि मुझे "कास्ट हल नहीं किया जा सकता" – leora

+0

@leora 'सिस्टम का उपयोग कर। लिंक्स;' –

+0

हम्म। । । मेरे पास पहले से ही संदर्भ है। । । – leora

23

यह सी # की विशेष रूप से भ्रमित विशेषता है। यहाँ सौदा है।

इस चर्चा के दौरान हम मानते हैं कि एक सरणी का तत्व प्रकार संदर्भ प्रकार नहीं है, मान प्रकार नहीं है।

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

string[] a1 = { "hello", "goodbye" }; 
object[] a2 = a1; // Legal 

आप तो a2 से बाहर एक तत्व प्राप्त करने की कोशिश करते हैं, तो यह काम करता है:

object o3 = a2[0]; 

कि कानूनी है, क्योंकि a2[0] वास्तव में a1[0] है, जो एक स्ट्रिंग है, जो वस्तु के लिए परिवर्तनीय है।

हालांकि, अगर आप सरणी लिखने करने का प्रयास तो आप क्रम में एक त्रुटि मिल जाएगा:

a2[0] = new object(); 

इस क्रम में विफल रहता है, क्योंकि a2वास्तव में है तार की एक सरणी और आप तारों की सरणी में एक गैर स्ट्रिंग नहीं डाल सकते हैं।

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

आप जिस सुविधा को चाहते हैं वह से भी अधिक टूटा हुआ है, और शुक्रिया का धन्यवाद सी # इसका समर्थन नहीं करता है। सुविधा आप चाहते है:

object[] a4 = { "Hello" }; 
string[] a5 = a4; 

कि असुरक्षित सरणी contravariance होगा। यह इस तरह से बुरी तरह टूट जाता है:

a4[0] = new Customer(); // Perfectly legal 
string s6 = a5[0]; 

और अब हम सिर्फ के प्रकार स्ट्रिंग एक चर में एक ग्राहक की नकल की।

आपको किसी भी तरह की सरणी या contravariance से बचना चाहिए; सरणी contravariance है, जैसा कि आपने पाया है, कानूनी नहीं है, और सरणी covariance आपके कार्यक्रम में कम समय बम बना रहा है जो अप्रत्याशित रूप से बंद हो जाता है। शुरू करने के लिए सही प्रकार के अपने सरणी बनाएं।

+1

मैं जो कुछ कहता हूं उससे सहमत हूं, लेकिन मैं इस बात से असहमत हूं कि एरे कॉन्ट्रैरिएंरिएंस सरणी कॉन्वर्सिस से _even more_ टूटा हुआ है - वे पूरी तरह से दोहरी स्थितियों की तरह लगते हैं। सरणी contravariance के साथ, आप ऑब्जेक्ट सरणी को पढ़ और लिख सकते हैं, स्ट्रिंग सरणी को लिख सकते हैं, और स्ट्रिंग सरणी से तब तक पढ़ सकते हैं जब तक ऑब्जेक्ट सरणी के माध्यम से उस स्थान पर किसी भिन्न प्रकार की ऑब्जेक्ट नहीं लिखा गया हो। कॉन्वर्सिस के साथ, आप स्ट्रिंग सरणी को पढ़ और लिख सकते हैं, ऑब्जेक्ट सरणी से पढ़ सकते हैं, और ऑब्जेक्ट सरणी को तब तक लिख सकते हैं जब तक आप उस स्थान में स्ट्रिंग डाल रहे हों। – kvb

+4

@kvb: मैं आपका बिंदु लेता हूं। मैं कहता हूं कि यह "और भी टूटा हुआ" है क्योंकि कॉन्वर्सेंट मामले में, टूटा हुआ परिदृश्य है: रूपांतरण-अनुवर्ती-लिखने में विफल रहता है। लेकिन चूंकि कई लोग सरणी का उपयोग * प्रभावशाली * रीड-ओनर एरे के रूप में करते हैं - वे केवल तब लिखते हैं जब सरणी बनाई जाती है - कोई रूपांतरण-बाद-लिखने वाला नहीं होता है, केवल पढ़ने के बाद ही रूपांतरण होता है। यही है, अगर रूपांतरण के बाद * लिखना * था तो यह * केवल * तोड़ सकता है। लेकिन contravariant मामला रूपांतरण के बाद * किसी भी * पढ़ने पर तोड़ सकता है; शायद सरणी शुरू करने के लिए सभी तार नहीं हो सकता है! –

0

वस्तु उन्मुख प्रोग्रामिंग में नियम है -

और "एक आधार वर्ग व्युत्पन्न वर्ग के लिए casted जा सकता है" व्युत्पन्न वर्ग हमेशा प्रकार आधार वर्ग के लिए casted जा सकता है "केवल वर्तमान उदाहरण है कि आधार वर्ग पकड़ अगर ऑफ वास्तव में कक्षा प्राप्त की गई है "

उदाहरण (ए का आधार है और बी ली गई है)

A a = new B(); // legal; 
B b = (B) a ; // legal as "a" is actually B (in first statement) 

अवैध:>

A a = new A(); 
B b = (B) a; // not legal as "a" is A only. 

यही बात वस्तु और स्ट्रिंग वर्गों के लिए लागू किया जाता है। ऑब्जेक्ट बेस क्लास है और स्ट्रिंग व्युत्पन्न कक्षा है।

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

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