2009-04-15 14 views
16

अभी मैं इसे Guid एस के साथ कर रहा हूं।स्पष्ट रूप से टाइप 'एक्स' से 'स्ट्रिंग' को परिवर्तित नहीं कर सकता - यह कब और कैसे तय करता है कि यह "नहीं कर सकता"?

मुझे निश्चित रूप से याद है कि कुछ स्थानों पर कोड के दौरान यह अंतर्निहित रूपांतरण काम करता है, अन्य में यह नहीं होता है। अब तक मैं पैटर्न देखने में विफल रहता हूं।

संकलक कैसे तय करता है जब यह तय नहीं कर सकता है? मेरा मतलब है, टाइप विधि Guid.ToString() मौजूद है, क्या इसे तब भी नहीं कहा जाता जब भी इस परिवर्तन की आवश्यकता होती है?

क्या कोई मुझे बता सकता है कि यह परिवर्तन किस परिस्थिति में स्वचालित रूप से किया जाता है और जब मुझे myInstance.ToString() स्पष्ट रूप से कॉल करना होता है?

+0

(जोड़ा गया टिप्पणी आपके प्रश्न) –

+0

परीक्षण और त्रुटि। परीक्षण त्रुटि विधि। – Will

उत्तर

32

संक्षेप में, एक अस्पष्ट या स्पष्ट रूपांतरण ऑपरेटर परिभाषित होती है जब:

class WithImplicit { 
    public static implicit operator string(WithImplicit x) { 
     return x.ToString();} 
} 
class WithExplicit { 
    public static explicit operator string(WithExplicit x) { 
     return x.ToString(); } 
} 
class WithNone { } 

class Program { 
    static void Main() { 
     var imp = new WithImplicit(); 
     var exp = new WithExplicit(); 
     var none = new WithNone(); 
     string s1 = imp; 
     string s2 = (string)exp; 
     string s3 = none.ToString(); 
    } 
} 
+2

बस इसे अपने लिए देखा। विश्वास नहीं कर सकता मैं इन सभी वर्षों में सी # के साथ इस बात को याद किया। मुझे लगता है कि इसे वास्तव में कभी भी जरूरी नहीं है ... आज मुझे कुछ नया सीखने के लिए धन्यवाद। – User

+0

और मुझे इस ऑपरेटर को कहां परिभाषित करना है? टाइप क्लास में मुझे लगता है? मैं इन अंतर्निहित और निष्पक्ष कक्षाओं के साथ स्थिर विस्तार नहीं जोड़ सकता। – User

+0

नहीं; एक्सटेंशन ऑपरेटर जैसी कोई चीज़ नहीं है। –

4

केवल जगह है जहाँ आप को प्रभावी ढंग से ToString कॉल करने के लिए की जरूरत नहीं है() अपने आप को जब तार श्रृंखलाबद्ध है।

Guid g; 
int i; 
string s = "Hello "+g+' '+i; 

तो फिर वहाँ इस तरह के String.Format() में के रूप में कुछ स्थितियों में, जहां कॉल .नेट फ्रेमवर्क द्वारा किया जाता है, कर रहे हैं।

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

+0

सही नहीं है; संकलक रूपांतरण ऑपरेटरों का भी सम्मान करता है। निहित और स्पष्ट रूपांतरण दोनों के उदाहरणों के लिए मेरी पोस्ट देखें, जो कॉलर को या तो ToString() या स्ट्रिंग concatenation का उपयोग करने की आवश्यकता नहीं है। –

+0

आप रूपांतरण ऑपरेटर के बारे में सही हैं, लेकिन मैं आमतौर पर उनसे बचता हूं इसलिए मैंने उन्हें यहां उल्लेख नहीं किया।मैं अपनी प्रतिक्रिया बदल दूंगा। – Lucero

4

नहीं, GUID से String से कोई अंतर्निहित रूपांतरण नहीं है, इसलिए यह कोड में कहीं भी काम नहीं करता है।

यह केवल तभी काम करता है जहां एक स्पष्ट रूपांतरण है, लेकिन रूपांतरण बहुत दिखाई नहीं दे सकता है। उदाहरण के लिए, जब आप तार जोड़:

string id = "--" + guidValue + " : " + num; 

यह GUID से String को एक अंतर्निहित रूपांतरण की तरह लग सकता है, लेकिन ऐसा नहीं है। कोड है कि वास्तव में उत्पन्न होता है इस तरह दिखता है:

string id = String.Concat(new object[] { "--", guidValue, " : ", num }); 

सभी ऑपरेंड प्रकार Object को डाल सकते हैं और एक सरणी में रखा जाता है। String.Concat विधि तब उनके लिए स्ट्रिंग प्रस्तुति प्राप्त करने के लिए सरणी में प्रत्येक आइटम के लिए ToString विधि को कॉल करती है।

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

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