2008-08-05 13 views
78

संभव डुप्लिकेट के रूप में वस्तु:
Casting vs using the 'as' keyword in the CLRकास्टिंग: (newtype) बनाम newtype

क्या वास्तव में इन दोनों डाले बीच का अंतर है?

SomeClass sc = (SomeClass)SomeObject; 
SomeClass sc2 = SomeObject as SomeClass; 

आम तौर पर, दोनों को निर्दिष्ट प्रकार के लिए स्पष्ट होना चाहिए?

+1

यह भी देखें http://stackoverflow.com/questions/496096/casting-vs-using-the-as-keyword-in-the-clr। यह पहला था, लेकिन उसमें एक अच्छा जवाब है। –

+1

आपने दूसरा सबसे पुराना प्रश्न पोस्ट किया है जो कि दूसरे का डुप्लिकेट है (पहला लॉक है)! बधाई हो, मुझे लगता है? – gparyani

+0

जो मजाकिया है क्योंकि यह 3 महीने पहले पोस्ट किया गया था :) लेकिन दूसरे के पास अधिक विस्तृत उत्तर हैं। –

उत्तर

82

यदि स्रोत प्रकार को लक्ष्य प्रकार पर नहीं डाला जा सकता है तो पूर्व अपवाद फेंक देगा। उत्तरार्द्ध परिणामस्वरूप एस 2 एक शून्य संदर्भ होगा, लेकिन कोई अपवाद नहीं है।

[संपादित करें]

मेरे मूल जवाब निश्चित रूप से सबसे स्पष्ट अंतर है, लेकिन एरिक Lippert points out के रूप में, यह केवल एक नहीं है। अन्य मतभेदों में शामिल हैं:

  • आप '' के रूप में ऑपरेटर एक प्रकार है कि एक मूल्य
  • आप परिवर्तित करने के लिए '' के रूप में उपयोग नहीं कर सकते के रूप में स्वीकार नहीं करता है 'अशक्त' के लिए कास्ट करने के लिए उपयोग नहीं कर सकते चीजें, जैसे कि एक अलग प्रतिनिधित्व के लिए संख्याएं (int के लिए तैरना, उदाहरण के लिए)।

और अंत में, 'as' बनाम कास्ट ऑपरेटर का उपयोग करके, आप यह भी कह रहे हैं "मुझे यकीन नहीं है कि यह सफल होगा या नहीं।"

1

कास्ट प्रयास विफल होने पर मूलभूत कलाकार एक अपवाद फेंकता है। अगर कास्ट प्रयास विफल रहता है तो "as" कास्ट शून्य हो जाता है।

1

वे अलग-अलग अपवाद फेंक देंगे।
(): NullReferenceException
के रूप में: InvalidCastException
जो डिबगिंग के लिए मदद कर सकता है।

"as" कीवर्ड ऑब्जेक्ट को डालने का प्रयास करता है और यदि कास्ट विफल हो जाता है, तो शून्य को चुपचाप वापस कर दिया जाता है। कास्ट ऑपरेटर तत्काल अपवाद फेंक देगा अगर कास्ट विफल हो जाता है।

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

कोड उदाहरण और एक अधिक विवरण के लिए: http://blog.nerdbank.net/2008/06/when-not-to-use-c-keyword.html

+0

(-1) के रूप में एक अवैधCastException फेंक नहीं होगा। – Keith

27
इसके अलावा

ध्यान दें कि आप केवल एक संदर्भ प्रकार या एक नल प्रकार

यानी साथ कीवर्ड के रूप में उपयोग कर सकते हैं:

double d = 5.34; 
int i = d as int; 

नहीं होगा संकलन

double d = 5.34; 
int i = (int)d; 

संकलित करेगा।

+1

क्योंकि एक कास्टिंग – CiNN

4

यहाँ एक अच्छा तरीका प्रक्रिया है कि उनमें से प्रत्येक का पालन करें कि मैं जब तय करने के लिए जो मेरे परिस्थिति के लिए बेहतर है की कोशिश कर रहा का उपयोग याद करने के लिए है।

DateTime i = (DateTime)value; 
// is like doing 
DateTime i = value is DateTime ? value as DateTime : throw new Exception(...); 

और अगले अनुमान लगाना यह

DateTime i = value as DateTime; 
पहले मामले में

क्या करता है, तो मूल्य एक अपवाद दूसरे मामले में फेंक दिया जाता है की तुलना में ढाला नहीं जा सकता है, तो मूल्य ढाला नहीं जा सकता आसान होना चाहिए , मैं शून्य करने के लिए सेट है।

तो पहले मामले में कड़ाई से रोका, तो डाली दूसरा डाली एक नरम बंद किया जाता है में विफल रहता है और आप बाद में एक NullReferenceException सामना कर सकते हैं किया जाता है।

1

यह पारसे और ट्राईपर्स के बीच का अंतर है। जब आप उम्मीद करते हैं कि यह असफल हो सकता है तो आप TryParse का उपयोग करते हैं, लेकिन जब आपके पास मजबूत आश्वासन होता है तो यह असफल नहीं होगा आप पार्स का उपयोग करेंगे।

3

Rytmis's comment पर विस्तार करने के लिए, आप के रूप में structs (Value Types) के लिए कीवर्ड का उपयोग नहीं कर सकते, क्योंकि उनके पास कोई शून्य मान नहीं है।

9

"as" का उपयोग करके टाइपकास्टिंग निश्चित रूप से बहुत तेज़ होता है जब कास्ट विफल रहता है, क्योंकि यह अपवाद फेंकने की कीमत से बचाता है।

लेकिन जब कलाकार सफल होता है तो यह तेज़ नहीं होता है। http://www.codeproject.com/KB/cs/csharpcasts.aspx पर आलेख भ्रामक है क्योंकि यह समझ में नहीं आता कि यह क्या माप रहा है।

लब्बोलुआब यह है:

  • आप डाली सफल होने के लिए (अर्थात एक विफलता असाधारण होगा), एक डाली का उपयोग की आशा करते हैं।

  • यदि आप अगर यह सफल होगा पता नहीं है, "के रूप में" ऑपरेटर का उपयोग और बातिल के लिए परिणाम का परीक्षण करें।

1

VB.NET अनुभव, (प्रकार) के साथ आप के उन लोगों के लिए DirectCast रूप में ही है और "प्रकार के रूप में" TryCast के समान है।

2

इस के सभी प्रकार के संदर्भ के लिए लागू होता है, मूल्य प्रकार as कीवर्ड का उपयोग नहीं कर सकते हैं के रूप में वे खाली नहीं रह सकती।

//if I know that SomeObject is an instance of SomeClass 
SomeClass sc = (SomeClass) someObject; 


//if SomeObject *might* be SomeClass 
SomeClass sc2 = someObject as SomeClass; 

कास्ट वाक्यविन्यास तेज है, लेकिन केवल सफल होने पर, यह असफल होने में धीमा है।

//we need to know what someObject is 
SomeClass sc; 
SomeOtherClass soc; 

//use as to find the right type 
if((sc = someObject as SomeClass) != null) 
{ 
    //do something with sc 
} 
else if ((soc = someObject as SomeOtherClass) != null) 
{ 
    //do something with soc 
} 

लेकिन यदि आप पूरी तरह से सुनिश्चित करें कि someObject की SomeClass तो कलाकारों का उपयोग एक उदाहरण है कर रहे हैं:

सर्वश्रेष्ठ अभ्यास as उपयोग करने के लिए जब आप प्रकार पता नहीं है है।

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

5

दो दृष्टिकोणों के बीच एक अंतर यह है कि पहला ((कुछ क्लास) ओबीजे) type converter कहलाता है।

4

खैर ऑपरेटर 'के रूप में' "में मदद करता है" आप अपनी समस्या को दफनाने रास्ता कम क्योंकि जब यह एक असंगत उदाहरण प्रदान की जाती है यह शून्य वापस आ जाएगी, हो सकता है आपको लगता है कि एक विधि को पारित करेंगे जो इसे दूसरे करने के लिए पारित करेंगे और इसलिए और अंततः आपको एक NullReferenceException मिलेगा जो आपके डिबगिंग को कठिन बना देगा।

इसका दुरुपयोग न करें। 99% मामलों में प्रत्यक्ष कास्ट ऑपरेटर बेहतर है।

+0

परिवर्तित नहीं करता है यहां बहुत अच्छी सलाह है। पाठक, कृपया इस पर विचार करें। – mbadawi23

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