2012-11-20 31 views
5

निम्नलिखित सी # कोड को देखते हुए:सी # में काम नहीं करना काम नहीं कर रहा है?

var a = new[] {"123", "321", 1}; //no best type found for implicitly typed array 

और VB.NET में अपने समकक्ष:

Dim a = {"123", "321", 1} 'no errors 

ऐसा लगता है कि VB.NET, सही ढंग से a = Object() के प्रकार के अनुमान लगाने के लिए सक्षम है, जबकि सी # शिकायत जब तक ऊपर करने के लिए तय हो गई है:

var a = new object[] {"123", "321", 1}; 

वहाँ उपरोक्त परिदृश्य के लिए सी # में ऑटो-अनुमान प्रकार के लिए एक रास्ता है?

संपादित करें: एक सी # खिलौने के डिब्बे में विभिन्न प्रकार के साथ खेलने के बाद दिलचस्प अवलोकन - प्रकार सही ढंग से मान लिया जाता है, तो सभी तत्वों को विरासत पेड़ में आम माता-पिता है, और है कि माता-पिता नहीं एक Object है, या तत्व हो सकता है अगर एक व्यापक प्रकार में डालें (परिशुद्धता के नुकसान के बिना, उदाहरण के लिए Integer -> Double)। तो इन दोनों को काम करेगा:

var a = new[] {1, 1.0}; //will infer double[] 
var a = new[] {new A(), new B()}; //will infer A[], if B inherits from A 

मुझे लगता है कि इस व्यवहार सी # में असंगत है, क्योंकि सभी प्रकार Object से विरासत, तो यह किसी भी अन्य प्रकार की तुलना में काफी अलग पूर्वज नहीं है। यह शायद एक डिज़ाइन है, इसलिए बहस करने का कोई मतलब नहीं है, लेकिन यदि आप कारण जानते हैं, तो जानना दिलचस्प होगा कि क्यों।

+0

बस उत्सुक, तो आप एक लेबल वस्तु का उपयोग कर बंद बेहतर होगा एक untyped सरणी के बजाय? – CookieOfFortune

+0

@CookieOfFortune: कभी-कभी मुझे प्रोटोटाइप कारणों के लिए त्वरित और गंदे कोड लिखने की आवश्यकता होती है, अक्सर एसओ पर अन्य लोगों की सहायता के लिए। इस उद्देश्य के लिए एक वस्तु बनाना संभव नहीं है। – Neolisk

+0

क्षमा करें, मेरा मतलब एक अज्ञात वस्तु है: var a = new {Str1 = "123", स्ट्र 2 = "321", AnInteger = 1}; – CookieOfFortune

उत्तर

9

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

आप निश्चित रूप से करने के लिए objectकिसी भी तत्व की डाली सकता है:

var a = new[] { (object) "123", "321", 1}; 

... लेकिन फिर आप के साथ-साथ सिर्फ एक स्पष्ट रूप से टाइप किया सरणी प्रारंभकर्ता उपयोग कर सकते हैं:

var a = new object[] {"123", "321", 1}; 

या ऐसे मामलों में जहां आप वास्तव में एक ही समय में एक चर घोषित कर रहे हैं:

object[] a = {"123", "321", 1}; 
+0

पर्याप्त मेला। पूरी तरह से स्पष्टीकरण के लिए धन्यवाद। – Neolisk

2

नहीं। हालांकि, आप वैकल्पिक स्पष्टीकरण, विकल्प सख्त चालू, और विकल्प अंतर का उपयोग करके वीबी को सी # की तरह व्यवहार कर सकते हैं।

Best Practices: Option Infer

+0

क्या मैं सी # को वीबी की तरह व्यवहार कर सकता हूं? – Neolisk

+2

+1 @ जोश सी: मैं नहीं कहूंगा "आप कर सकते हैं", लेकिन "आपको करना है!" @Neolisk: नए _dynamic_ कीवर्ड 'गतिशील [] के = {"123", "1", 1} का उपयोग करें;' अब आपके पास "कुछ" है ... – igrimpe

+0

+1 विकल्प स्पष्ट ** होना चाहिए ** पर! विकल्प सख्त ** लगभग हमेशा ** होना चाहिए। लेकिन आप विकल्प को छोड़ना चाहेंगे अन्यथा आप LINQ का उपयोग नहीं कर सकते हैं। – MarkJ

1

सी # में आप dynamic इस्तेमाल कर सकते हैं: dynamic[] k = { "1", 2, "3" };

यह करता है की नकल न वीबी के व्यवहार completey, हालांकि। dynamic[] k = { "1", "2", "3" }; अभी भी आपको ऑब्जेक्ट की एक सरणी देता है, जबकि वीबी में आपको स्ट्रिंग की एक सरणी मिलती है।

और निश्चित रूप से:

dynamic[] k = { "1", "3", "3" }; 
int i = k[0].I_do_not_exist(); 

समस्या के बिना संकलित है, लेकिन सबसे अधिक संभावना बुरी तरह असफल होगा;)

+0

+1। – Neolisk

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