2009-07-23 19 views
64

यह वास्तव में कोई समस्या नहीं है, हालांकि मैं उत्सुक हूं। जब मैं स्ट्रिंग को सहेजता हूं तो डेटारो कहता है, इसे ऑब्जेक्ट में डाला जाता है। जब मैं इसका उपयोग करना चाहता हूं, तो मुझे इसे ToString डालना होगा। जहाँ तक मुझे पता के रूप में वहाँ ऐसा करने के कई तरीके हैं, पहलेकास्टिंग बनाम किसी ऑब्जेक्ट को स्ट्रिंग में कनवर्ट करना, जब ऑब्जेक्ट वास्तव में एक स्ट्रिंग है

string name = (string)DataRowObject["name"]; //valid since I know it's a string 

है और एक अन्य एक है:

string name = DataRowObject["name"].ToString(); 

मैं क्या दोनों के बीच अंतर है में दिलचस्पी है? क्या पहला और कुशल है? (यह सिर्फ एक अटकलें है, मेरे सिर ToString() विधि में कुछ लूपिंग तंत्र द्वारा कार्यान्वित किया जाता है जहां इसे कास्टिंग करना "तेज़" हो सकता है, हालांकि यह सिर्फ "आंत महसूस" है)।

क्या ऐसा करने का एक तेज़/अधिक सुरुचिपूर्ण तरीका भी है?

क्या कोई इसे मेरे लिए साफ़ कर सकता है?

+3

मुझे पता है कि आपने बताया है कि ऑब्जेक्ट एक स्ट्रिंग है, लेकिन आपको यह सुनिश्चित नहीं है कि लौटाया गया ऑब्जेक्ट शून्य है, तो आप "कन्वर्ट.ओस्ट्रिंग (डेटारोव ऑब्जेक्ट [" नाम "]) का उपयोग करके भी कास्ट कर सकते हैं;" किसी भी शून्य संदर्भ अपवाद से बचने के लिए, यदि ऑब्जेक्ट शून्य है, तो खाली स्ट्रिंग (string.empty) को वापस करने का अतिरिक्त लाभ है। – n00b

उत्तर

47

दोनों अलग उद्देश्यों के लिए लक्षित हैं। किसी भी ऑब्जेक्ट की ToString विधि उस ऑब्जेक्ट का स्ट्रिंग प्रस्तुत करना है। कास्टिंग काफी अलग है, और 'as' key शब्द एक सशर्त कास्ट करता है, क्योंकि कहा गया है। 'As' कुंजी शब्द मूल रूप से कहता है "मुझे का संदर्भ उस ऑब्जेक्ट पर प्राप्त करें यदि ऑब्जेक्ट इस प्रकार है" जबकि ToString कहता है "मुझे उस ऑब्जेक्ट का स्ट्रिंग प्रस्तुति प्राप्त करें"।नतीजा कुछ मामलों में समान हो सकता है लेकिन दोनों को को अदला-बदली माना नहीं जा सकता क्योंकि, जैसा कि मैंने कहा था, वे विभिन्न उद्देश्यों के लिए मौजूद हैं। यदि आपका इरादा डालना है तो आपको हमेशा कास्ट का उपयोग करना चाहिए, न कि ToString।

http://www.codeguru.com/forum/showthread.php?t=443873

से

इस मामले में भी http://bytes.com/groups/net-c/225365-tostring-string-cast

+0

तो अगर मैं इसे सही ढंग से समझता हूं। .ToString हमेशा वस्तु की एक स्ट्रिंग वापस आ जाएगा। जबकि कास्टिंग विफल हो जाएगी अगर इसे स्ट्रिंग के रूप में वापस नहीं किया जा सकता है? – DaImTo

+1

@DaImTo: जब आप टाइप ए से टाइप करने के लिए किसी ऑब्जेक्ट को बी (यदि कास्टिंग) सफलता टाइप करते हैं, तो आपके पास एक नई ऑब्जेक्ट होगी, जिसे आप फिर से एक प्रकार में डाल सकते हैं। कास्टिंग बदल नहीं है वे कौन हैं (मूल), लेकिन बदलें कि उन्हें क्या देखा जाएगा। सामान्य मामलों में कनवर्ट करना एक तरफा टिकट है। यह पुरानी वस्तु के लिए एक नई वस्तु (केवल) का प्रतिनिधित्व करता है। पूर्व: स्ट्रिंग() में कनवर्ट करते समय एक छात्र ऑब्जेक्ट सेंट छात्र की तरह एक स्ट्रिंग लुक होगा: @ 1343; 43234। क्या आपको लगता है कि आप इसे उस छात्र में वापस कर सकते हैं जिसमें फ़ील्ड मूल्य है? – Andiana

+0

@ एंड्रियाना इन रेफ परीक्षा पुस्तक सी # के लिए यह कहती है, "अपने स्वयं के प्रकार बनाते समय, आप अपनी ऑब्जेक्ट के स्ट्रिंग प्रस्तुति को वापस करने के लिए ToString को ओवरराइड कर सकते हैं। यदि आवश्यक हो, तो आप एक पार्स और TryParse विधि बना सकते हैं जो स्ट्रिंग बैक को परिवर्तित करता है मूल ऑब्जेक्ट में। IFormattable इंटरफ़ेस को कार्यान्वित करने के लिए आवश्यक है कि आपकी ऑब्जेक्ट को कन्वर्ट क्लास द्वारा उपयोग किया जा सके। " क्या आप इसे पहले जो कहा था उसके प्रकाश में समझा सकते हैं। धन्यवाद –

27

यदि आपको पता है कि यह String है तो हर तरह से इसे String पर डालें। वर्चुअल विधि को कॉल करने से आपकी ऑब्जेक्ट को कास्ट करना तेज होगा।

संपादित करें:

============ Casting vs. virtual method ============ 
cast 29.884 1.00 
tos 33.734 1.13 

मैं इस्तेमाल किया जॉन स्कीट के इस तरह BenchmarkHelper:

using System; 
using BenchmarkHelper; 

class Program 
{ 
    static void Main() 
    { 
     Object input = "Foo"; 
     String output = "Foo"; 

     var results 
      = TestSuite.Create("Casting vs. virtual method", input, output) 
      .Add(cast) 
      .Add(tos) 
      .RunTests() 
      .ScaleByBest(ScalingMode.VaryDuration); 

     results.Display(ResultColumns.NameAndDuration | ResultColumns.Score, 
       results.FindBest()); 
    } 

    static String cast(Object o) 
    { 
     return (String)o; 
    } 

    static String tos(Object o) 
    { 
     return o.ToString(); 
    } 
} 

तो ऐसा लगता है कि कास्टिंग थोड़ा तेजी से वास्तव में यहाँ कुछ बेंच मार्किंग के परिणाम हैं ToString() पर कॉल करने से।

+1

@ एंड्रयू: क्या आपने इसे बेंचमार्क किया है? यह अच्छी तरह से बदल सकता है, लेकिन आखिरी बार मैंने इसे बेंचमार्क किया था, मैंने पाया कि वर्चुअल विधि वास्तव में तेज़ थी। मुझे उम्मीद नहीं थी, लेकिन यह था। –

+0

@ जोन - नहीं मैंने नहीं किया!मुझे यह सुनिश्चित करने के लिए इसे देखना होगा। –

+1

@ एंड्रयूहेयर- जॉन का लिंक स्ट्रिंग.ToString() – TheGeekZn

16

असल में आपके मामले में टाइप कास्ट छोड़ना बेहतर है क्योंकि। ToString() बग छुपा सकता है। उदाहरण के लिए, आपका डेटा बेस स्कीमा बदल गया है और नाम अब स्ट्रिंग प्रकार का नहीं है लेकिन .ToString() के साथ आपका कोड अभी भी काम करता है। तो इस मामले में टाइप कास्ट का उपयोग करना बेहतर है। कुछ खास नहीं =)

public override string ToString() 
{ 
    return this; 
} 
+5

+1 की ओर जाता है, जैसा कि आप सोचते हैं उतना धीमा नहीं हो सकता है - कृपया मेरा उत्तर देखें। –

5

downcasting एक अपेक्षाकृत धीमी गति से ऑपरेशन के बाद से CLR विभिन्न क्रम प्रकार- जांच करने के लिए किया गया है -

यहाँ String.ToString के कार्यान्वयन() है। हालांकि, string पर इस विशेष परिदृश्य में ToString() को स्थिरता के लिए कॉल करने से अधिक उपयुक्त है (आप ToInt32 पर object पर कॉल नहीं कर सकते हैं, लेकिन इसे int पर रखें) और रखरखाव।

+0

को कम करने के लिए 505 –

2

देखें:

string name = DataRowObject["name"].ToString(); 

क्योंकि यह एक string है, मुझे लगता है कि एक स्ट्रिंग वस्तु की ToString() पद्धति के रूप में सरल है:

return this; 

इसलिए आईएमएचओ में कोई प्रदर्शन जुर्माना नहीं है।

पीएस मैं जावा प्रोग्रामर हूं, इसलिए यह anwser केवल अनुमान है।

+0

मुझे लगता है कि DataRowObject को ऑब्जेक्ट्स के रूप में सबकुछ का कोई ज्ञान नहीं है और स्टोर करता है, इसलिए यह निश्चित रूप से इसे वापस करने के समान सरल नहीं है। –

+3

@martjin_himself ऑब्जेक्ट ओरिएंटेशन की दुनिया में आपका स्वागत है, मुझे आपको एक नया मित्र पेश करने दें: पॉलिमॉर्फिज्म। – fortran

+0

@fortran क्या आप विस्तार से बात करेंगे? मुझे पता है कि सबकुछ एक वस्तु है और बहुरूपता आपको एक स्ट्रिंग का इलाज करने की अनुमति देती है जैसे कि यह एक वस्तु थी, हालांकि यह अप्रासंगिक है, जब तक कि मुझे कुछ याद नहीं आ रहा है? चीयर्स –

1

ToString() डिफ़ॉल्ट रूप से एक कलाकार नहीं करता है। इसका उद्देश्य एक स्ट्रिंग को वापस करना है जो प्रकार का प्रतिनिधित्व करता है (उदा। "System.Object")।

यदि आप कास्टिंग से बचना चाहते हैं तो आप दृढ़ता से टाइप किए गए कार्यान्वयन के बारे में सोचने का प्रयास कर सकते हैं (जेनिक्स का उपयोग करके, उदाहरण के लिए) और DataRowObject पूरी तरह से बचाता है।

2

डेटा ऑब्जेक्ट के लिए, मैं आपको निम्न कोड जैसे "as" कीवर्ड का उपयोग करने का सुझाव देता हूं।

string name = DataRowObject["name"] as string; 

कृपया मूल्य का उपयोग करने से पहले इसे जांचें। स्ट्रिंग नाम = (स्ट्रिंग) DataRowObject [ "नाम"] एक अपवाद आप मिल जाएगा: की वस्तु कास्ट करने में असमर्थ

if(name != null) 
{ 
    // statement for empty string or it has value 
} 
else 
{ 
    // statement for no data in this object.  
} 
+0

यह एक और अधिक संस्करण होगा: 'string name = (पंक्ति ["नाम"] स्ट्रिंग के रूप में) ?? "डिफ़ॉल्ट"; ' –

4

मैं एक और टिप्पणी

बनाने के लिए आप कास्टिंग का उपयोग करने जा रहे हैं, तो चाहते हैं यदि डेटाबेस तालिका में रिकॉर्ड शून्य मान है तो 'सिस्टम.डबुल' टाइप करने के लिए 'System.DBNull' टाइप करें। मैं जानता हूँ कि स्ट्रिंग नाम = DataRowObject [ "नाम"] ToString() या

आप

if(!string.IsNullOrEmpty(DataRowObject["name"].ToString())) 
{ 
string name = (string)DataRowObject["name"]; 
} 
else 
{ 
//i.e Write error to the log file 
string error = "The database table has a null value"; 

} 
0

की तरह शून्य मान के लिए जाँच करने के लिए है आपको लगता है कि उल्लेख किया:

इस परिदृश्य में आप का उपयोग करने के लिए है। ऑब्जेक्ट एक स्ट्रिंग है, लेकिन आपको डर है कि लौटाया गया ऑब्जेक्ट शून्य है, आप "कन्वर्ट टॉस्ट्रिंग (DataRowObject [" name "]) का उपयोग करके भी कास्ट कर सकते हैं;" किसी भी शून्य संदर्भ अपवाद से बचने के लिए, यदि ऑब्जेक्ट शून्य है, तो रिक्त स्ट्रिंग (string.empty) को वापस करने का अतिरिक्त लाभ है (बेशक जब तक आप ऐसे मामलों में अपवाद नहीं चाहते हैं)।

+0

" कनवर्ट टॉस्ट्रिंग "का उपयोग करने के लिए एक अतिरिक्त लाभ है और यह है कि आप एक अपवाद फेंक दिए बिना शून्य मूल्य में गुजर सकते हैं। [कड़ी] (http://msdn.microsoft.com/en-us/library/astxcyeh.aspx) – Remy

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