Convert.To () विधि का उपयोग करने और उपयोग करने के बीच अंतर


91

मेरे पास एक फ़ंक्शन है जो मूल्यों doubleपर कास्ट stringकरता है।

string variable = "5.00"; 

double varDouble = (double)variable;

एक कोड परिवर्तन की जाँच की गई और परियोजना त्रुटि के साथ बनती है: System.InvalidCastException: Specified cast is not valid.

हालाँकि, निम्नलिखित करने के बाद ...

string variable = "5.00"; 

double varDouble = Convert.ToDouble(variable);

... परियोजना बिना किसी त्रुटि के बनती है।

कास्टिंग और Convert.To()विधि का उपयोग करने के बीच क्या अंतर है ? कास्टिंग एक Exceptionका उपयोग Convert.To()करता है और क्यों नहीं करता है?

c#  casting 


6
एक संदर्भित प्रश्न के संबंध में , ओपी पूछता है कि कास्ट या कन्वर्ट का उपयोग कब किया जाए, और स्वीकृत उत्तर में कहा गया है, "यह वास्तव में आपके द्वारा उपयोग किए जाने वाले विकल्प का मामला है।" मैं एक कास्ट बनाम एक कन्वर्ट के बीच का अंतर पूछ रहा हूं। मेरी राय में, नीचे दिए गए उत्तर (कुडोस एसओ!) मतभेदों के बारे में अधिक विवरण प्रदान करते हैं "बनाम इस या उस विकल्प का उपयोग करके" ... और इस विवरण का उपयोग अधिक सूचित विकल्प बनाने के लिए किया जा सकता है, संक्षेप में।

@ edmastermind29 प्रोग्रामिंग संदर्भ में "x और y के बीच अंतर क्या है" और "x और y का उपयोग कब करें" के बीच बहुत अंतर नहीं है। दोनों परस्पर उत्तर देते हैं।
नवाफल

2
लगभग 3 साल बाद, यह प्रकट नहीं होता है कि एक इस मामले में दूसरे का जवाब देता है। प्रश्न: "X और Y में क्या अंतर है?" एक: "यह वास्तव में पसंद की बात है जो भी आप उपयोग करते हैं।" बहुत उपयोगी नहीं है।

किसी के पास इसका सीधा जवाब नहीं है, जिसमें सर्वश्रेष्ठ प्रदर्शन भी सवाल का हिस्सा है, अपने अनुभव से मैं कास्ट को विशेष रूप से इस तरह के स्तंभ मान प्राप्त करने में बेहतर है .. (इंट) datatable.Rows [0] [0], अगर हम इसके 100% int
Sundara Prabu

जवाबों:


127

यहां तक ​​कि अगर आप उन्हें किसी भी तरह देख सकते हैं, तो वे उद्देश्य में पूरी तरह से अलग हैं। आइए सबसे पहले यह परिभाषित करने का प्रयास करें कि कलाकार क्या है:

कास्टिंग एक डेटा प्रकार की इकाई को दूसरे में बदलने की क्रिया है।

यह थोड़ा सामान्य है और यह किसी भी तरह से रूपांतरण के बराबर है क्योंकि एक कास्ट में अक्सर रूपांतरण का समान सिंटैक्स होता है, इसलिए सवाल यह होना चाहिए कि भाषा द्वारा किसी कास्ट (निहित या स्पष्ट) की अनुमति है और आपको कब उपयोग करना है ( अधिक) स्पष्ट रूपांतरण?

मुझे पहले उनके बीच एक सरल रेखा खींचनी है। औपचारिक रूप से (भले ही भाषा वाक्य रचना के लिए समतुल्य हो) एक कलाकार प्रकार को बदल देगा जबकि एक रूपांतरण विल / मान बदल सकता है (अंततः प्रकार के साथ मिलकर )। साथ ही एक कास्ट प्रतिवर्ती है जबकि रूपांतरण नहीं हो सकता है।

यह विषय बहुत बड़ा है, इसलिए आइए इसे खेल से कस्टम कास्ट ऑपरेटरों को छोड़कर थोड़ा संकीर्ण करने का प्रयास करें।

निहित जाति

C # में एक कास्ट तब लगाया जाता है जब आप कोई जानकारी नहीं खोते हैं (कृपया ध्यान दें कि यह चेक प्रकारों के साथ किया जाता है न कि उनके वास्तविक मूल्यों के साथ )।

आदिम प्रकार

उदाहरण के लिए:

int tinyInteger = 10;
long bigInteger = tinyInteger;

float tinyReal = 10.0f;
double bigReal = tinyReal;

ये जातियाँ अंतर्निहित हैं क्योंकि रूपांतरण के दौरान आप किसी भी जानकारी को नहीं खोएंगे (आप केवल प्रकार को व्यापक बनाते हैं)। रूपांतरण के दौरान इसके वास्तविक मानों की परवाह किए बिना इसके विपरीत निहित कलाकारों की अनुमति नहीं है (क्योंकि उन्हें केवल रन-टाइम पर जांचा जा सकता है), रूपांतरण के दौरान आप कुछ जानकारी खो सकते हैं। उदाहरण के लिए यह कोड संकलित नहीं करेगा क्योंकि doubleइसमें (और वास्तव में ऐसा हो सकता है) एक मान का प्रतिनिधित्व करने योग्य नहीं है float:

// won't compile!
double bigReal = Double.MaxValue;
float tinyReal = bigReal;

वस्तुओं

ऑब्जेक्ट (पॉइंटर) के मामले में, कास्ट हमेशा अंतर्निहित होता है जब कंपाइलर सुनिश्चित कर सकता है कि स्रोत प्रकार एक व्युत्पन्न वर्ग है (या यह लक्ष्य वर्ग के प्रकार को लागू करता है), उदाहरण के लिए:

string text = "123";
IFormattable formattable = text;

NotSupportedException derivedException = new NotSupportedException();
Exception baseException = derivedException;

इस मामले में कंपाइलर जानता है कि stringलागू होता है IFormattableऔर वह NotSupportedException(इससे प्राप्त होता है) Exceptionइसलिए कास्ट निहित है। कोई जानकारी नहीं खोई है क्योंकि ऑब्जेक्ट उनके प्रकार नहीं बदलते हैं (यह structs और आदिम प्रकार के साथ अलग है क्योंकि एक कलाकार के साथ आप एक अन्य प्रकार की एक नई वस्तु बनाते हैं ), उनमें से आपके विचारों में क्या परिवर्तन होता है।

स्पष्ट जाति

एक कास्ट स्पष्ट है जब रूपांतरण संकलक द्वारा नहीं किया जाता है और फिर आपको कास्ट ऑपरेटर का उपयोग करना चाहिए। आमतौर पर इसका मतलब है कि:

  • आप जानकारी या डेटा खो सकते हैं, इसलिए आपको इसके बारे में पता होना चाहिए।
  • रूपांतरण विफल हो सकता है (क्योंकि आप एक प्रकार को दूसरे में परिवर्तित नहीं कर सकते हैं) इसलिए, फिर, आपको पता होना चाहिए कि आप क्या कर रहे हैं।

आदिम प्रकार

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

double precise = Math.Cos(Math.PI * 1.23456) / Math.Sin(1.23456);
float coarse = (float)precise;

float epsilon = (float)Double.Epsilon;

दोनों उदाहरणों में, भले ही मान floatसीमा के भीतर हो , आप जानकारी (इस मामले में सटीक) खो देंगे ताकि रूपांतरण स्पष्ट हो। अब यह प्रयास करें:

float max = (float)Double.MaxValue;

यह रूपांतरण विफल हो जाएगा, फिर से, यह स्पष्ट होना चाहिए ताकि आप इसके बारे में जानते हों और आप एक चेक कर सकें (उदाहरण में मान स्थिर है, लेकिन यह कुछ रन-टाइम संगणना या I / O से आ सकता है)। अपने उदाहरण पर वापस जाएं:

// won't compile!
string text = "123";
double value = (double)text;

यह संकलित नहीं करेगा क्योंकि संकलक पाठ को संख्याओं में परिवर्तित नहीं कर सकता है। पाठ में कोई भी वर्ण हो सकते हैं, केवल संख्या नहीं और यह बहुत अधिक है, सी # में, यहां तक ​​कि एक स्पष्ट कलाकारों के लिए (लेकिन इसे किसी अन्य भाषा में अनुमति दी जा सकती है)।

वस्तुओं

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

// won't compile!    
string text = (string)AppDomain.Current;
Exception exception = (Exception)"abc";

यह कोड संकलित करेगा लेकिन यह रन-टाइम पर विफल हो सकता है (यह प्रभावी वस्तुओं के प्रकार पर निर्भर करता है) a InvalidCastException:

object obj = GetNextObjectFromInput();
string text = (string)obj;

obj = GetNextObjectFromInput();
Exception exception = (Exception)obj;

रूपांतरण

तो, आखिरकार, यदि जाति रूपांतरण हैं, तो हमें कक्षाओं की आवश्यकता क्यों है Convert? Convertकार्यान्वयन और IConvertibleकार्यान्वयन से आने वाले सूक्ष्म अंतरों को अनदेखा करना क्योंकि सी # में एक कास्ट के साथ आप कंपाइलर को कहते हैं:

मेरा विश्वास करो, यह प्रकार उस प्रकार का है, भले ही आप इसे अब नहीं जान सकते, मुझे ऐसा करने दें और आप देखेंगे।

-या-

चिंता मत करो, मुझे परवाह नहीं है अगर इस रूपांतरण में कुछ खो जाएगा।

किसी और चीज के लिए एक अधिक स्पष्ट ऑपरेशन की आवश्यकता है ( आसान कलाकारों के निहितार्थ के बारे में सोचें , यही कारण है कि सी ++ ने उनके लिए लंबे, क्रियात्मक और स्पष्ट वाक्यविन्यास पेश किए हैं)। इसमें एक जटिल ऑपरेशन शामिल हो सकता है ( string-> doubleरूपांतरण एक पार्सिंग की आवश्यकता होगी)। stringउदाहरण के लिए, रूपांतरण हमेशा संभव होता है ( ToString()विधि के माध्यम से ) लेकिन इसका मतलब यह हो सकता है कि आप जो अपेक्षा करते हैं उससे कुछ अलग हो सकता है इसलिए यह एक कास्ट से अधिक स्पष्ट होना चाहिए ( जितना आप लिखते हैं, उतना ही आप जो कर रहे हैं उसके बारे में सोचते हैं )।

इस रूपांतरण को ऑब्जेक्ट के अंदर किया जा सकता है (उस के लिए ज्ञात आईएल निर्देशों का उपयोग करके), कस्टम रूपांतरण ऑपरेटरों (कास्ट करने के लिए वर्ग में परिभाषित) या अधिक जटिल तंत्र ( TypeConverterउदाहरण के लिए वर्ग या विधि) का उपयोग करके। आप इस बात से अवगत नहीं हैं कि ऐसा करने के लिए क्या होगा, लेकिन आप जानते हैं कि यह विफल हो सकता है (इसीलिए जब अधिक नियंत्रित रूपांतरण संभव हो तो IMO का उपयोग करना चाहिए)। आपके मामले में रूपांतरण केवल stringउत्पादन करने के लिए पार्स करेगा double:

double value = Double.Parse(aStringVariable);

बेशक यह विफल हो सकता है यदि आप ऐसा करते हैं तो आपको हमेशा उस अपवाद को पकड़ना चाहिए जो वह फेंक सकता है ( FormatException)। यह विषय से बाहर है लेकिन जब कोई TryParseउपलब्ध होता है तो आपको इसका उपयोग करना चाहिए (क्योंकि शब्दार्थ आप कहते हैं कि यह संख्या नहीं हो सकती है और यह और भी तेज़ है ... विफल होने के लिए)।

.NET में रूपांतरण बहुत से स्थानों से आ सकते हैं, TypeConverterउपयोगकर्ता परिभाषित रूपांतरण ऑपरेटरों के साथ अंतर्निहित / स्पष्ट जातियों, IConvertibleऔर लागू करने के तरीकों (क्या मैं कुछ भूल गया हूं?)। उनके बारे में अधिक जानकारी के लिए MSDN पर एक नज़र डालें।

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

float? maybe = 10; // Equals to Nullable<float> maybe = 10;
float sure1 = (float)maybe; // With cast
float sure2 = maybe.Value; // Without cast

इस मामले में यह स्पष्ट है क्योंकि यह विफल हो सकता है लेकिन यह कार्यान्वयन के लिए है (भले ही इस बारे में दिशा-निर्देश हों)। कल्पना कीजिए कि आप इस तरह एक कस्टम स्ट्रिंग क्लास लिखते हैं:

EasyString text = "123"; // Implicit from string
double value = (string)text; // Explicit to double

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

double value = "123";

किसी भी प्रकार से अंतर्निहित रूपांतरण की अनुमति (चेक रन-टाइम पर किया जाएगा)। उचित विकल्पों के साथ यह किया जा सकता है, उदाहरण के लिए, VB.NET में। यह सिर्फ एक अलग दर्शन है।

मैं उनके साथ क्या कर सकता हूं?

तो अंतिम प्रश्न यह है कि आपको एक या दूसरे का उपयोग कब करना चाहिए। आइए देखें कि आप एक स्पष्ट कास्ट का उपयोग कब कर सकते हैं:

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

केवल पहला रूपांतरण आपके साथ Convertऐसा हो सकता है, जिसके लिए आपके पास कोई विकल्प नहीं है और आपको एक स्पष्ट कलाकार का उपयोग करने की आवश्यकता है।

आइए अब देखें कि आप कब उपयोग कर सकते हैं Convert:

  • किसी भी आधार प्रकार से दूसरे आधार प्रकार के रूपांतरण (कुछ सीमाओं के साथ, MSDN देखें )।
  • किसी भी प्रकार के रूपांतरण जो IConvertibleकिसी अन्य (समर्थित) प्रकार पर लागू होते हैं।
  • byteस्ट्रिंग से / के लिए / से एक सरणी के लिए रूपांतरण ।

निष्कर्ष

IMO Convertका उपयोग हर बार किया जाना चाहिए जब आप जानते हैं कि रूपांतरण विफल हो सकता है (प्रारूप के कारण, सीमा के कारण या क्योंकि यह असमर्थित हो सकता है), भले ही वही रूपांतरण किसी कास्ट के साथ किया जा सकता है (जब तक कि कुछ और उपलब्ध न हो)। यह स्पष्ट करता है कि आपके कोड को कौन पढ़ेगा और आपका इरादा क्या है और यह विफल हो सकता है (डीबग को सरल बनाते हुए)।

बाकी सब के लिए आपको एक कास्ट का उपयोग करने की आवश्यकता है, कोई विकल्प नहीं है, लेकिन अगर एक और बेहतर तरीका उपलब्ध है, तो मेरा सुझाव है कि आप इसका उपयोग करें। अपने उदाहरण में से एक रूपांतरण stringकरने के लिए doubleकुछ है कि (पाठ उपयोगकर्ता से आता है, खासकर अगर) अक्सर एक का उपयोग कर उदाहरण के लिए असफल हो जायेगी तो आप ज्यादा स्पष्ट हो सके (इसके अलावा आप इसे पर अधिक नियंत्रण होता) के रूप में यह सुनिश्चित करना चाहिए, है TryParseविधि।

संपादित करें: उनके बीच क्या अंतर है?

अद्यतन प्रश्न के अनुसार और जो मैंने पहले लिखा था ( जब आप उपयोग कर सकते हैं / की तुलना में आप कास्ट का उपयोग कर सकते हैं के बारे में Convert) तब अंतिम बिंदु स्पष्ट करने के लिए है कि क्या उनके बीच अंतर है (इसके अलावा Convertउपयोग IConvertibleऔर IFormattableइंटरफेस इसलिए यह ऑपरेशन कर सकता है कलाकारों के साथ अनुमति नहीं है)।

संक्षिप्त उत्तर हाँ है, वे अलग तरह से व्यवहार करते हैं । मैं Convertक्लास को एक हेल्पर मेथड्स क्लास की तरह देखता हूं इसलिए अक्सर यह कुछ लाभ या थोड़ा अलग व्यवहार प्रदान करता है। उदाहरण के लिए:

double real = 1.6;
int castedInteger = (int)real; // 1
int convertedInteger = Convert.ToInt32(real); // 2

बहुत अलग है, है ना? कलाकारों ने छंटनी की (यह वही है जो हम सभी अपेक्षा करते हैं) लेकिन Convertनिकटतम पूर्णांक के लिए एक गोलाई प्रदर्शन करता है (और यदि आप इसके बारे में नहीं जानते हैं तो यह उम्मीद नहीं की जा सकती है)। प्रत्येक रूपांतरण पद्धति में अंतरों का परिचय दिया जाता है, इसलिए एक सामान्य नियम लागू नहीं किया जा सकता है और उन्हें मामले द्वारा देखा जाना चाहिए ... 19 आधार प्रकार हर दूसरे प्रकार में बदलने के लिए ... सूची बहुत लंबी हो सकती है, MSDN मामले से परामर्श करने के लिए बहुत बेहतर है मामला!


मैं, सवाल पूछने के लिए बदल गया Difference between casting and using the Convert.To() method। अन्यथा, बहुत व्यापक जवाब। (मुझे उम्मीद है कि मेरा सवाल फिर से खुल गया है ...)

@ edmastermind29 मैंने थोड़ा सा प्रश्न संपादित किया, एक लंबे उत्तर के लिए विषय बहुत लंबा है (सूची में 300 से अधिक संभव रूपांतरण)। धर्मान्तरित लाभ (या सिर्फ अप्रत्याशित व्यवहार?) न केवल बनाम जातियों बल्कि "सादे" IConvertible और IFormattable इंटरफेस भी जोड़ता है।
एड्रियानो रेपेट्टी

मैं सी से उधार ली गई धारणा को नापसंद करता हूं doubleजो उन मूल्यों का प्रतिनिधित्व करते हैं जो पूरी संख्याओं का प्रतिनिधित्व नहीं करते हैं, "परिवर्तनीय" होना चाहिए int। एक डाली मामलों में जहां जैसे एक पुन: प्राप्त करने में उचित प्रतिमान प्रतीत होता है Int32एक से मूल्यों को double[]जो वास्तविक संख्या और का मिश्रण रखती है Int32मानों को बदल दिया गया है double[कि प्रदर्शनीय नहीं है एक मूल्य में परिवर्तित करने की कोशिश ठीक में int32एक अनपेक्षित स्थिति का संकेत होगा और एक अपवाद को ट्रिगर करना चाहिए], लेकिन मुझे लगता है कि जब कोई एक हानिकारक रूपांतरण चाहता है, तो जिस रूप में वह चाहता है, उसके बारे में विशिष्ट होना चाहिए।
सुपरकैट

1
एक अन्य अंतर वस्तु से आदिम प्रकार तक है। जैसेobject o = 123; var l = Convert.ToInt64(o); var i = (long) (int) o; var f = (long) o // InvalidCastException
yue shi

1
@ rory.ap यह एक महत्वपूर्ण बिंदु है। नहीं, औपचारिक रूप से वह एक कास्ट ( float-> int) नहीं है बल्कि एक जबरदस्ती है । एक कलाकार उदाहरण के लिए हो सकता है DerivedClass-> BaseClass। यह भ्रामक है क्योंकि C # में हम दोनों के लिए एक ही शब्द (और ऑपरेटर) का उपयोग करते हैं लेकिन वे वास्तव में अलग चीजें हैं। उनके बीच अंतर करने की एक औपचारिक परिभाषा जो मैंने लिखी है, उससे थोड़ी अधिक जटिल है।
एड्रियानो रेपेट्टी

13

कास्टिंग संकलक को बताने का एक तरीका है, "मुझे पता है कि आपको लगता है कि यह चर एक बार है, लेकिन मैं आपसे अधिक जानता हूं; वस्तु वास्तव में एक फू है, इसलिए मुझे इसका इलाज करने दें जैसे कि यह एक फू से था। अब से।" फिर, रनटाइम में, यदि वास्तविक वस्तु वास्तव में एक फू बनती है तो आपका कोड काम करता है, अगर यह पता चला कि वह वस्तु बिल्कुल भी फू नहीं थी, तो आपको एक अपवाद मिलेगा। (विशेष रूप से System.InvalidCastException)

दूसरी ओर परिवर्तित करना यह कहने का एक तरीका है, "यदि आप मुझे एक प्रकार की वस्तु बार देते हैं तो मैं एक ब्रांड नई फू ऑब्जेक्ट बना सकता हूं जो उस बार ऑब्जेक्ट में क्या दर्शाता है। मैं मूल वस्तु को नहीं बदलूंगा, यह जीता है ' t मूल वस्तु को अलग तरह से समझें, यह कुछ नया पैदा करेगा जो सिर्फ कुछ अन्य मूल्य पर आधारित है । जैसा कि यह होगा कि यह कैसे होगा, यह कुछ भी हो सकता है। इसके मामले में Convert.ToDoubleकॉलिंग समाप्त हो जाएगी।Double.Parseयह निर्धारित करने के लिए सभी प्रकार के जटिल तर्क हैं कि किस प्रकार के तार किस संख्यात्मक मान का प्रतिनिधित्व करते हैं। आप अपनी स्वयं की रूपांतरण विधि लिख सकते हैं जो स्ट्रिंग्स को मैप करने के लिए अलग से युगल बनाता है (शायद संख्याओं को प्रदर्शित करने के लिए कुछ पूरी तरह से अलग सम्मेलन का समर्थन करने के लिए, जैसे कि रोमन अंक या जो भी हो)। एक रूपांतरण कुछ भी कर सकता है, लेकिन विचार यह है कि आप संकलक को आपके लिए कुछ भी करने के लिए नहीं कह रहे हैं; आप एक नया कोड बनाने के लिए कोड लिखने वाले हैं क्योंकि संकलक, आपकी मदद के बिना, यह जानने का कोई तरीका नहीं है कि कैसे नक्शा (उदाहरण के रूप में) stringसे ए double

तो, आप कब कनवर्ट करते हैं, और कब डालते हैं? दोनों ही मामलों में हमारे पास एक प्रकार का कुछ चर होता है, आइए A कहते हैं, और हम चाहते हैं कि B का एक चर हो। यदि हमारी A वस्तु वास्तव में, वास्तव में, हुड के नीचे, B है, तो हम डालते हैं। यदि यह वास्तव में बी नहीं है, तो हमें इसे परिवर्तित करने की आवश्यकता है, और परिभाषित करें कि प्रोग्राम को ए से बी प्राप्त करने के लिए कैसे माना जाता है।


SO पोस्ट में से एक में एरिक लिपर्ट ने उल्लेख किया कि अंतर्निहित कास्ट नाम की कोई चीज नहीं है और यह अंतर्निहित रूपांतरण है । मैं कास्ट और कन्वर्सेशन को एक दूसरे के साथ इस्तेमाल कर रहा हूं। "निहित कलाकार" कहने में क्या गलत है? क्या रूपांतरण किसी भी कलाकार की आवश्यकता के बिना निहित नहीं है, तो कोई इसे "निहित कलाकार" कह सकता है?
rahulaga_dev

1
@RahulAgarwal क्या एक डाली है एक ऑपरेशन है जिसमें आप की जरूरत है स्पष्ट रूप से संकेत मिलता है कि किसी दिए गए प्रकार है (या बनाया जा सकता है) एक और प्रकार का मान्य उदाहरण। जब एक अंतर्निहित रूपांतरण मौजूद होता है, तो टाइप को दूसरे प्रकार के रूप में मानने के लिए किसी कलाकार की आवश्यकता नहीं होती है। इसलिए "निहित कलाकारों" से कोई मतलब नहीं है (संभवतः एरिक जैसी कुछ स्थितियों को छोड़कर, जहां एक कास्ट ऑपरेटर को डेवलपर टाइप किए बिना जोड़ा जाता है, जैसे उपयोग करते समय foreach)। उनमें से किसी अपवाद के बाहर, डाले हैं परिभाषा से स्पष्ट।
Servy

6

से MSDN:

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

निम्नलिखित उदाहरण पर विचार करें:

double a = 2548.3;
int b;
b = (int)a; //2548 --> information (.3) lost in the conversion

और भी:

एक कास्ट स्पष्ट रूप से संकलक को सूचित करने का एक तरीका है जिसे आप रूपांतरण बनाने का इरादा रखते हैं और आप जानते हैं कि डेटा हानि हो सकती है।

System.Convertजब आप गैर-संगत प्रकारों के बीच कनवर्ट करना चाहते हैं तो आप कक्षा का उपयोग कर सकते हैं । मुख्य अंतर यह है के बीच कास्टिंग और परिवर्तित है संकलन और चलाने के समयरन-टाइम पर टाइप रूपांतरण अपवाद दिखाई देते हैं , यानी रन-टाइम में विफल रहने वाले एक प्रकार InvalidCastExceptionको फेंक दिया जाएगा।


निष्कर्ष: कास्टिंग में आप कंपाइलर को बता रहे हैं जो aवास्तव में टाइप है bऔर यदि ऐसा है तो प्रोजेक्ट बिना किसी त्रुटि के बनता है जैसे कि उदाहरण:

double s = 2;
int a = (int) s;

लेकिन रूपांतरण में तुम कह रहे हो से एक नई वस्तु बनाने के लिए एक तरह से है संकलक करने aके प्रकार b, कृपया इसे करते हैं और परियोजना किसी भी त्रुटि के बिना बनाता है लेकिन जैसा कि मैंने कहा है, तो प्रकार डाली रन-टाइम में विफल रहता है, यह एक कारण होगा InvalidCastExceptionकरने के लिए फेंका जाना

उदाहरण के लिए नीचे दिया गया कोड कभी संकलित नहीं होता है क्योंकि कंपाइलर यह पता लगाता है कि टाइप DateTimeकरने के लिए किस प्रकार की अभिव्यक्ति नहीं डाली जा सकती है int:

DateTime s = DateTime.Now;
int a = (int)(s);

लेकिन यह एक सफलतापूर्वक संकलित है:

DateTime s = DateTime.Now;
int a = Convert.ToInt32(s);

लेकिन रन-टाइम में आपको वह मिलेगा InvalidCastExceptionजो कहता है:

अमान्य दिनांक 'DateTime' से 'Int32' तक।


4

अपने उदाहरण में आप एक स्ट्रिंग को एक डबल (गैर अभिन्न प्रकार) में डालने का प्रयास कर रहे हैं।

काम करने के लिए एक स्पष्ट रूपांतरण आवश्यक है।

और मुझे कहना होगा कि आप इस्तेमाल कर सकते हैं Convert.ToDoubleConvert.ToInt64 जब आप एक इंट में परिवर्तित होते हैं तो आप दोहरे मूल्य के आंशिक भागों को खो सकते हैं, इसके बजाय कर सकते थे।

यदि आपके वैरिएबल का मान "5.25" है, तो varDouble 5.00 होगा (Int64 में रूपांतरण के कारण 0.25 का नुकसान)

कास्टिंग बनाम कनवर्टिंग के बारे में आपके प्रश्न का उत्तर देने के लिए।

आपका कलाकार (एक स्पष्ट कलाकार) एक स्पष्ट कलाकार के लिए आवश्यकताओं को पूरा नहीं करता है। जो मूल्य आप कास्ट ऑपरेटर के साथ डालने की कोशिश कर रहे हैं वह अमान्य है (यानी गैर अभिन्न)।

कास्टिंग / रूपांतरण के नियमों के लिए इस MSDN पृष्ठ पर जाएं


@ edmastermind29 मैंने अपना उत्तर अपडेट कर दिया है। मुझे आशा है कि यह आपके प्रश्न का उत्तर देगा।
scartag

एक स्पष्ट कलाकारों के लिए क्या आवश्यकताएं हैं ... मेरे प्रश्न से संबंधित हैं? क्या यह "गैर अभिन्न" मूल्य के संबंध में है?

@ edmastermind29 हाँ। यदि आप किसी संख्यात्मक प्रकार को कास्ट करने की कोशिश कर रहे हैं तो वह गैर-न्यूमेरिक है, कास्ट अमान्य है .. एक रूपांतरण की आवश्यकता है।
scartag

4

Convert.Doubleविधि वास्तव में सिर्फ आंतरिक रूप से कहता है Double.Parse(string)विधि।

न तो Stringप्रकार और न हीDouble प्रकार दो प्रकारों के बीच एक स्पष्ट / अंतर्निहित रूपांतरण को परिभाषित करते हैं, इसलिए कास्टिंग हमेशा विफल रहेगी।

Double.Parseविधि में प्रत्येक चरित्र पर नजर डालेंगे stringऔर में पात्रों के मूल्यों पर आधारित एक अंकीय मान का निर्माण string। यदि कोई वर्ण अमान्य है, तो Parseविधि विफल हो जाती है (विधि विफल होने के कारण Convert.Doubleभी)।


1
और यह एक स्पष्ट कलाकारों से कैसे भिन्न होता है?

3
एक स्पष्ट कलाकार डेटा प्रकार क्या है, यह सिर्फ बाइट्स पर नहीं दिखता है। एक उदाहरण एक पूर्णांक के लिए x x = '1' कास्टिंग होगा, पूर्णांक 49 होगा क्योंकि cahracter '1' ascii तालिका में # 49 है
user1751547

@ user1751547 तो, क्या Convert.ToDouble()बाइट से परे एक नज़र का उपयोगकर्ता डेटा पर विचार करेगा?

@ user1751547 मुझे लगता है कि इस तरह के अंतर्ज्ञान की आवश्यकता है जो इस प्रश्न का सही उत्तर देने में आवश्यक है। सीधे शब्दों में "यह परिभाषित नहीं है" थोड़ा मूट है।
एंट पी

@ edmastermind29 हाँ, यह इनपुट प्रकार को देखेगा, और यदि यह एक तार था, तो यह प्रत्येक वर्ण के माध्यम से जाएगा, यह जानते हुए कि यदि चार का एससीआई मान 49 था, तो यह '1' वर्ण है और इसे ठीक से परिवर्तित करें
उपयोगकर्ता 1751547

3

कास्टिंग में कोई रूपांतरण शामिल नहीं है, अर्थात किसी मूल्य का आंतरिक प्रतिनिधित्व नहीं बदला गया है। उदाहरण:

object o = "Hello"; // o is typed as object and contains a string.
string s = (string)o; // This works only if o really contains a string or null.

तुम एक में बदल सकते हैं doubleकरने के लिए stringयह पसंद

double d = 5;
string s = d.ToString(); // -> "5"

// Or by specifying a format
string formatted = d.ToString("N2"); // -> "5.00"

आप stringएक doubleको कई तरीकों से परिवर्तित कर सकते हैं (यहाँ सिर्फ उनमें से दो):

string s = "5";
double d = Double.Parse(s); // Throws an exception if s does not contain a valid number

या सुरक्षित तरीका है

string s = "5";
double d;
if (Double.TryParse(s, out d)) {
    Console.WriteLine("OK. Result = {0}", d);
} else {
    Console.WriteLine("oops!");
}

Convert.ToDouble()आंतरिक रूप से कहता हैDouble.Parse() । यह मेरे लाभ के लिए उपयोग करने के लिए Convert.ToDouble()है Double.Parse()या नहीं और क्यों?

Convert.ToDoubleबहुत सारे अधिभार हैं जो विभिन्न प्रकार के इनपुट को स्वीकार करते हैं। अधिभार को स्वीकार stringरिटर्न 0.0अगर एक nullस्ट्रिंग पारित कर दिया है। इसके अलावा, मुझे इसका उपयोग करने में कोई कमी नहीं दिख रही है।
ओलिवियर जैकोट-डेस्कोम्स

तो, या तो ... या Double.Parse()प्रस्ताव के लिए कुछ है जो मुझे विचार करना चाहिए?

Double.Parse()से अधिक प्रत्यक्ष है Convert.ToDouble()। यदि आप सुनिश्चित हैं कि आपके स्ट्रिंग में एक वैध संख्या होगी, तो आप इसे सुरक्षित रूप से उपयोग कर सकते हैं, अन्यथा मैं आपको उपयोग करने की सलाह देता हूं Double.TryParse
ओलिवियर जैकोट-डेसकोम्बर्स

1
string variable = "5.00";     
double varDouble = (double)variable;

उपरोक्त रूपांतरण को केवल भाषा द्वारा अनुमति नहीं है। यहाँ संख्यात्मक प्रकारों के लिए स्पष्ट जातियों की एक सूची दी गई है: http://msdn.microsoft.com/en-us/library/yht2cx7b.aspx जैसा कि आप देख सकते हैं, यहां तक ​​कि प्रत्येक संख्यात्मक प्रकार को दूसरे संख्यात्मक प्रकार में परिवर्तित नहीं किया जा सकता है

यहाँ कास्टिंग के बारे में कुछ और जानकारी

और यह Convert.ToDouble () में कैसे भिन्न होता है?

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

लेकिन जब आप स्ट्रिंग को एक नंबर पर लाने की कोशिश कर रहे हैं, तो आप ऐसा नहीं कर सकते क्योंकि यह चर द्वारा ली गई मेमोरी की मात्रा को बदलने के लिए पर्याप्त नहीं है। उदाहरण के लिए, 5.00एक स्ट्रिंग के रूप में "संख्या" का एक क्रम है: 53 (5) 46 (।) 48 (0) 48 (0) - जो कि ASCII के लिए है, लेकिन स्ट्रिंग में कुछ समान होगा। यदि संकलक एक स्ट्रिंग से पहले एन (4 डबल के लिए? निश्चित नहीं) बाइट्स ले जाएगा - उस टुकड़े में पूरी तरह से अलग डबल नंबर होगा। उसी समय Convert.ToDouble () विशेष एल्गोरिथ्म चलाएं जो एक स्ट्रिंग के प्रत्येक प्रतीक को ले जाएगा, अंक का पता लगाएगा जो इसे दर्शाता है और आपके लिए एक डबल नंबर बनाता है, यदि स्ट्रिंग एक संख्या का प्रतिनिधित्व करता है। PHP जैसी भाषाएं, मोटे तौर पर बोलना, पृष्ठभूमि में आपके लिए Convert.ToDouble कॉल करें। लेकिन C #, एक स्टेटिकली टाइप की गई भाषा की तरह, आपके लिए ऐसा नहीं करेगा। यह आपको यह सुनिश्चित करने की अनुमति देता है कि कोई भी ऑपरेशन सुरक्षित है और आपको कुछ अप्रत्याशित नहीं मिलेगा जैसे कि:

double d = (double)"zzzz"

@ edmastermind29 मेरा अद्यतन उत्तर देखें। मैंने उसे समझाने की कोशिश की है। स्पष्टीकरण एकदम सही है, लेकिन मान लीजिए कि यह अंतर स्पष्ट करता है।
विक्टर एस।

1

स्ट्रिंग को डबल की तरह कास्टिंग करने की अनुमति नहीं है C # जिसके कारण आपको अपवाद प्राप्त होता है, आपको स्ट्रिंग को परिवर्तित करने की आवश्यकता होती है ( MSDN डॉक्स जो स्वीकार्य रूपांतरण पथ दिखाता है)। यह केवल इसलिए है क्योंकि एक स्ट्रिंग में संख्यात्मक डेटा शामिल नहीं है, लेकिन विभिन्न संख्यात्मक प्रकार (शून्य मानों को छोड़कर) होगा। A Convertएक विधि चलाएगा जो यह देखने के लिए स्ट्रिंग की जांच करेगा कि क्या इसे संख्यात्मक मूल्य में बदल दिया जा सकता है। यदि यह हो सकता है, तो यह उस मूल्य को लौटा देगा। यदि यह नहीं हो सकता है, यह एक अपवाद फेंक देंगे।

इसे परिवर्तित करने के लिए, आपके पास कई विकल्प हैं। आपने Convertअपने प्रश्न में विधि का उपयोग किया है , Parseजो काफी हद तक समान है Convert, लेकिन आपको TryParse को देखना चाहिए जो आपको करने की अनुमति देगा:

string variable = "5.00"; 

double varDouble;

if (Double.TryParse(variable, out varDouble)) {
    //Code that runs if the conversion succeeded.
} else {
    //Code that runs if the conversion failed.
}

यह संभव अपवाद से बचना चाहिए जिसे आपको Convertया Parseगैर-संख्यात्मक स्ट्रिंग के लिए प्रयास करना चाहिए ।


यह मेरे लाभ एक का उपयोग करने के लिए है TryParseसे अधिक Convertहै क्योंकि TryParseजांच करता है कि रूपांतरण सफल होता है?

@ edmastermind29 मुझे ऐसा लगता है। यदि रूपांतरण विफल हो जाता है तो रूपांतरण अपवाद को फेंक देगा। ट्रायपार्स एक बूलियन लौटाएगा, यह सच है कि यदि रूपांतरण सफल होता है और यदि यह विफल होता है तो गलत है।
कीन

1

double varDouble = (double)variableमानता है कि variableपहले से ही एक डबल है। यदि variableयह डबल नहीं है (यह एक स्ट्रिंग है) तो यह विफल हो जाएगा। double varDouble = Convert.ToDouble(variable)यह पसंद है कहते हैं - यह धर्मान्तरित।यदि यह पार्स कर सकता है या अन्यथा एक डबल निकाल सकता हैvariable तो यह होगा।

मैं दूसरे का उपयोग कर रहा हूं Double.Parseया Double.TryParseक्योंकि यह अधिक स्पष्ट रूप से इंगित करता है कि क्या होने वाला है। आप एक स्ट्रिंग के साथ शुरू कर रहे हैं और यह एक डबल करने के लिए परिवर्तनीय होने की उम्मीद कर रहे हैं। यदि कोई संदेह है, तो उपयोग करें TryParse

यदि variableएक विधि तर्क है, तो टाइप को डबल में बदलें। सही प्रकार प्रदान करने के लिए फोन करने वाले को जिम्मेदार बनाएं। इस तरह से कंपाइलर आपके लिए काम करता है।


-1

सबसे महत्वपूर्ण अंतर यह है कि यदि टाइप कास्टिंग का उपयोग किया जाता है और रूपांतरण विफल होता है (कहते हैं कि हम int के लिए एक बहुत बड़े फ्लोट मान को परिवर्तित कर रहे हैं) कोई अपवाद नहीं फेंका जाएगा और एक न्यूनतम मान जो पकड़ सकता है वह दिखाया जाएगा। लेकिन कन्वर्ट का उपयोग करने के मामले में , इस तरह के परिदृश्यों के लिए एक अपवाद फेंक दिया जाएगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.