2012-09-23 8 views
9

मैं थोड़ी देर के लिए कुछ कोड पर काम कर रहा हूं। और मेरा एक सवाल था: कास्टिंग, पार्सिंग और कनवर्ट करने में क्या अंतर है? और जब हम उनका उपयोग कर सकते हैं?कास्टिंग, पार्सिंग और कनवर्टिंग के बीच अंतर

उत्तर

12

कास्टिंग तब होती है जब आप एक प्रकार का चर लेते हैं और इसे एक अलग प्रकार में बदलते हैं। आप केवल कर सकते हैं कि कुछ मामलों में, इसलिए जैसे:

string str = "Hello"; 
object o = str; 
string str2 = (string)o; // <-- This is casting 

कास्टिंग नहीं परिवर्तन वेरिएबल का मान करता है - मूल्य एक ही प्रकार (स्ट्रिंग "नमस्ते") की बनी हुई है।

परिवर्तित होता है जब आप एक प्रकार से एक मूल्य लेने के लिए और यह एक अलग प्रकार में बदलने का:

double d = 5.5; 
int i = (int)d; // <---- d was converted to an integer 

ध्यान दें कि इस मामले में, रूपांतरण कास्टिंग के रूप में किया गया था।

पार्सिंग एक स्ट्रिंग ले रहा है और इसे अपनी सामग्री को समझकर इसे एक अलग प्रकार में परिवर्तित कर रहा है। उदाहरण के लिए, स्ट्रिंग "123" को संख्या 123 में परिवर्तित करना, या "शनिवार, 22 सितंबर" स्ट्रिंग को डेटटाइम में परिवर्तित करना।

+0

बस विस्तृत करने के लिए: यह भी ध्यान दें कि सभी कास्ट मान्य नहीं हैं, यह निर्भर करता है कि प्रकार विरासत द्वारा संगत हैं या नहीं। यदि एक रूपांतरण ऑपरेटर परिभाषित किया गया है, तो यह कास्टिंग की तरह दिखने पर भी रूपांतरण में होगा। –

+0

हैलो। बस सोच रहा है, क्या आप जानते हैं कि तेज़ कौन सा है? – fungusanthrax

1

कास्टिंग डेटा प्रकार के बीच परिवर्तित एक डाली

static void _Casting() 
{ 
    int i = 10; 
    float f = 0; 
    f = i; // An implicit conversion, no data will be lost. 
    f = 0.5F; 
    i = (int)f; // An explicit conversion. Information will be lost. 
} 

का उपयोग कर पार्स करने स्पष्ट रूप से किया जा सकता है (प्रकार काम करने के लिए कास्टिंग संगत होने की जरूरत है) (पार्सिंग विभिन्न प्रकार के बीच रूपांतरण :) है एक प्रकार धर्मान्तरित करने के लिए एक और प्रकार

int num = int.Parse("500"); 

एक्सएमएल की तरह डेटा आइटम के माध्यम से traversing int.parse पार्स uisng के रूप में कहा जा सकता है भी

012 पार्स करने के रूप में कहा जा सकता है

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

परिवर्तित वास्तव में सिर्फ आप इसे

के लिए और अधिक देखें http://msdn.microsoft.com/en-us/library/ms228360%28VS.80%29.aspx

+0

यहां कुछ ग़लत गलत जानकारी है। 'कास्टिंग' को मौजूदा ऑब्जेक्ट को केवल एक अलग प्रकार के रूप में _treat_ करना चाहिए (माना जाता है कि यह एक संगत अपस्टास्ट/डाउनकास्ट है) और डेटा को किसी नए ऑब्जेक्ट में कनवर्ट नहीं करना चाहिए। आपका उदाहरण वास्तव में नई वस्तुओं/डेटा बना रहा है। 'लागू रूपांतरण' _should_ का परिणाम डेटा के नुकसान में नहीं होता है, लेकिन उपयोगकर्ता द्वारा परिभाषित रूपांतरणों की बात होने पर इसकी गारंटी नहीं है। 'पार्सिंग' आम तौर पर 'स्ट्रिंग' प्रतिनिधित्व से कुछ समकक्ष वस्तु से सख्ती से होता है, न कि" एक प्रकार से दूसरे प्रकार "तक। रूपांतरण प्रकार प्रकार के रूप में रूपांतरण प्रकार के समान हो सकते हैं। –

+0

@ChrisSinclair मुझे लगता है कि आपको http://msdn.microsoft.com/en-us/library/ms228360%28VS.80%29.aspx – cc4re

2

पार्स में मदद करता है इन तीन शर्तों विशिष्ट उपयोगों के साथ प्रत्येक रहे हैं Convert श्रेणी का उपयोग करना:

  • कास्टिंग - बदल रहा है एक type अन्य को। ऐसा करने के लिए, प्रकार संगत: int ->object होना चाहिए; IList<T> ->IEnumerable<T>
  • पार्स - आम तौर पर तार पढ़ने और उपयोगी भागों
  • परिवर्तित निकालने के लिए संदर्भित करता - कास्टिंग के समान है, लेकिन आम तौर पर एक रूपांतरण एक अन्यथा गैर संगत प्रकार के एक प्रकार को बदलने शामिल होगा। इसका एक उदाहरण ऑब्जेक्ट्स को तारों में परिवर्तित कर देगा।

एक प्रकार से दूसरे में एक कलाकार को आमतौर पर विरासत या इंटरफ़ेस के कार्यान्वयन के माध्यम से संगतता के कुछ रूप की आवश्यकता होती है।कास्टिंग अंतर्निहित या स्पष्ट हो सकता है:

class Foo : IFoo { 
    // implementations 
} 

// implicit cast 
public IFoo GetFoo() { 
    return Foo; 
} 

// explicit cast 
public IFoo GetFoo() { 
    return Foo as IFoo; 
} 

पार्स करने के कुछ तरीके हैं। हम एक्सएमएल पार्सिंग के बारे में पढ़ते हैं; कुछ प्रकारों में Parse और TryParse विधियां हैं; और फिर कई बार हमें 'सामानों की देखभाल' करने के लिए तारों या अन्य प्रकारों को पार्स करने की आवश्यकता होती है।

int.Parse("3") // returns an integer value of 3 
int.TryParse("foo", out intVal) // return true if the string could be parsed; otherwise false 

कनवर्टिंग एक प्रकार को एक दूसरे के असंगत में बदल सकता है। इसमें कुछ पार्सिंग भी शामिल हो सकती है। रूपांतरण उदाहरण आमतौर पर, आईएमओ, विशिष्ट संदर्भों से बहुत अधिक बंधे होते हैं।

5

कास्टिंग: संकलक को यह बताते हुए कि कोई ऑब्जेक्ट वास्तव में इसे बदलने के बिना कुछ और है (हालांकि कुछ डेटा हानि हो सकती है)।

object obj_s= "12345"; 
string str_i = (string) obj; // "12345" as string, explicit 

int small = 12345; 
long big = 0; 
big = small; // 12345 as long, implicit 

पार्स: कार्यक्रम (क्रम पर) व्याख्या करने के लिए एक स्ट्रिंग बताना।

string int_s = "12345"; 
int i = int.Parse(int_s); // 12345 as int 

परिवर्तित: कार्यक्रम के तरीकों में बनाया का उपयोग करने के क्या बस विनिमेय नहीं हो सकता है के लिए प्रकार बदलने के लिए प्रयास करने के लिए बताना।

double dub = 123.45; 
int i = System.Convert.ToInt32(dub); // 123 as int 
+0

में गहराई से देखना है, आप निहित रूप से 'डबल'' को परिवर्तित नहीं कर सकते एक 'int' जैसा कि (आमतौर पर) जानकारी का नुकसान होता है। एक स्पष्ट रूपांतरण की आवश्यकता है इसलिए 'i = dub' संकलित नहीं होगा। इसके अलावा, impl _conversions_ _not_ कास्टिंग हैं। वे नए डेटा/ऑब्जेक्ट्स बनाते हैं। एक "निहित" _cast_ उदाहरण इसके बेस क्लास में उप-वर्ग को ऊपर उठाएगा। –

+0

http: // stackoverflow से।कॉम/ए/4181954/1615483 (डबल से int पर); "यदि आप डिफॉल्ट ट्रंकेट-टू-शून्य व्यवहार चाहते हैं तो आप ** ** कास्ट ** का उपयोग कर सकते हैं" –

+0

मैं 'int' से' long' के लिए संपादित करूंगा, इसलिए इसमें कोई संदेह नहीं है कि –

1

यह सवाल वास्तव में बहुत जटिल है ...

आम तौर पर, एक डाली सिर्फ क्रम बताता है एक से दूसरे प्रकार बदलने के लिए। ये ऐसे प्रकार होने चाहिए जो संगत हैं। उदाहरण के लिए int को हमेशा long के रूप में प्रदर्शित किया जा सकता है, इसलिए इसे long पर डालना ठीक है। कुछ जानवरों के दुष्प्रभाव होते हैं। उदाहरण के लिए, float इसकी सटीकता को छोड़ देगा यदि इसे int पर डाला गया है। तो (int)1.5f परिणामस्वरूप int मान 1. परिणाम आमतौर पर प्रकार बदलने का सबसे तेज़ तरीका है, क्योंकि यह एक एकल आईएल ऑपरेटर है। उदाहरण के लिए, कोड:

public void CastExample() 
    { 
     int i = 7; 
     long l = (long)i; 
    } 

आईएल कोड चलाकर डाली निष्पादित करता है:

conv.i8 //convert to 8-byte integer (a.k.a. Int64, a.k.a. long). 

एक पार्स कुछ समारोह है कि प्रकार एक बार में ले जाता है और एक और रिटर्न है। यह एक वास्तविक कोड फ़ंक्शन है, न केवल एक आईएल ऑपरेटर। यह आमतौर पर चलाने में अधिक समय लगता है, क्योंकि यह कोड की कई पंक्तियों को चलाता है।

उदाहरण के लिए, इस कोड:

public void ParseExample() 
    { 
     string s = "7"; 
     long l = long.Parse(s); 
    } 

चलाता आईएल कोड:

call  int64 [mscorlib]System.Int64::Parse(string) 

दूसरे शब्दों में यह एक वास्तविक प्रणाली को बुलाती है।

public static long Parse(String s) { 
     return Number.ParseInt64(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo); 
    } 

और Number.Parse: आंतरिक रूप से, Int64 प्रकार है कि तरीका प्रदान करता है

[System.Security.SecuritySafeCritical] // auto-generated 
    internal unsafe static Int64 ParseInt64(String value, NumberStyles options, NumberFormatInfo numfmt) { 
     Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes]; 
     NumberBuffer number = new NumberBuffer(numberBufferBytes); 
     Int64 i = 0; 

     StringToNumber(value, options, ref number, numfmt, false); 

     if ((options & NumberStyles.AllowHexSpecifier) != 0) { 
      if (!HexNumberToInt64(ref number, ref i)) { 
       throw new OverflowException(Environment.GetResourceString("Overflow_Int64")); 
      } 
     } 
     else { 
      if (!NumberToInt64(ref number, ref i)) { 
       throw new OverflowException(Environment.GetResourceString("Overflow_Int64")); 
      } 
     } 
     return i; 
    } 

और इसी तरह ...तो आप देख सकते हैं कि यह वास्तव में बहुत सारे कोड कर रहा है।


अब जहां चीजें अधिक जटिल हो कि हालांकि एक डाली आमतौर पर सबसे तेज है, क्लास अंतर्निहित और स्पष्ट डाली ऑपरेटरों को ओवरराइड कर सकते है। उदाहरण के लिए, अगर मैं वर्ग लिखें:

public class CastableClass 
{ 
    public int IntValue { get; set; } 

    public static explicit operator int(CastableClass castable) 
    { 
     return castable.IntValue; 
    } 
} 

मैं int के लिए स्पष्ट डाली ऑपरेटर अधिरोहित किया है, इसलिए मैं अब कर सकते हैं:

public void OverridedCastExample() 
    { 
     CastableClass cc = new CastableClass {IntValue = 7}; 
     int i = (int)cc; 
    } 

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

call  int32 UnitTestProject1.CastableClass::op_Explicit(class UnitTestProject1.CastableClass) 

तो वैसे भी, आप आमतौर पर कास्ट करने के लिए जब भी आप कर सकते हैं चाहता हूँ। फिर यदि आप नहीं कर सकते हैं तो पार्स करें।

+0

+1: बहुत अच्छे और विस्तृत उदाहरण हैं। – IAbstract

1

Casting: या पार्सिंग

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

TryParse

int.TryParse सी # भाषा में पूर्णांकों पार्स करने के लिए सबसे अधिक उपयोगी तरीकों में से एक है। यह विधि int.Parse जैसी ही काम करती है। int.TryParse अंदर संरचना की कोशिश और पकड़ है। इसलिए, यह अपवाद

Convert:

एक और आधार डेटा प्रकार के लिए एक आधार के डेटा प्रकार में कनवर्ट करता है फेंक नहीं है। Convert.ToInt32, इसके भाई बहन के साथ कनवर्ट करें। ToInt16 और Convert.ToInt64, वास्तव में int.Parse विधि के लिए एक स्थिर रैपर विधि है।

या Cast के बजाय TryParse का उपयोग कई प्रोग्रामर द्वारा अनुशंसित किया जाता है।

स्रोत: www.dotnetperls.com

+1

'TryParse' भ्रमित नहीं है और शब्दकोश के' TryGetValue' के समान पैटर्न का पालन करता है। साथ ही, स्ट्रिंग इनपुट शून्य या खाली होने पर 'TryParse' अपवाद फेंक देगा। – IAbstract

+0

धन्यवाद चेक किया गया। @ | सार –

0

अलग अलग लोगों के लिए इसका इस्तेमाल अलग अलग बातें मतलब है। इसे नेट दुनिया के बाहर सच होने की आवश्यकता नहीं है, लेकिन यह है कि मैंने एरिक लिपर्ट के ब्लॉग पढ़ने वाले नेट संदर्भ में समझा है:

एक रूप से दूसरे रूप में प्रकारों के सभी परिवर्तनों को रूपांतरण कहा जा सकता है। वर्गीकरण का एक तरीका यह

  1. निहित हो सकता है -

    एक।प्रतिनिधित्व बदलते (भी बुलाया बलात्कार)

    int i = 0; 
    double d = i; 
    
    object o = i; // (specifically called boxing conversion) 
    IConvertible o = i; // (specifically called boxing conversion) 
    

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

    बी। प्रतिनिधित्व (भी बुलाया अंतर्निहित संदर्भ रूपांतरण) संरक्षण

    string s = ""; 
    object o = s; 
    
    IList<string> l = new List<string>(); 
    

    केवल संदर्भ प्रकार के लिए मान्य, कभी नहीं वस्तु के संदर्भ पहचान बदल जाता है परिवर्तित किया जा रहा, रूपांतरण हमेशा की तरह, सफल होता संकलन समय पर गारंटी, कोई क्रम जाँच करता है।

  2. स्पष्ट (भी बुलाया कास्टिंग) -

    एक। प्रतिनिधित्व

    int i = 0; 
    enum e = (enum)i; 
    
    object o = i; 
    i = (int)o; // (specifically called unboxing conversion) 
    

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

    बी। प्रतिनिधित्व संरक्षण

    object o = ""; 
    string s = (string)o; 
    

    केवल संदर्भ प्रकार के लिए मान्य,, रूपांतरण या सफल नहीं हो सकता है (यह भी स्पष्ट संदर्भ रूपांतरण कहा जाता है) कभी नहीं वस्तु के संदर्भ पहचान बदल जाता है परिवर्तित किया जा रहा, संगतता के लिए क्रम की जांच करता है।

जबकि रूपांतरण भाषा के स्तर निर्माणों हैं, पार्स अर्थ में एक बिल्कुल अलग बात है यह ढांचा स्तर है, या दूसरे शब्दों में वे कस्टम तरीकों एक इनपुट से एक आउटपुट प्राप्त करने के लिए लिखा है, जैसे int.Parse जो string में लेता है और int देता है।

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