2010-02-16 14 views
5

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

निम्नलिखित कोड कार्यात्मक रूप से सही है, लेकिन मैं इसके साथ सहज नहीं हूं। शायद इस आराम पथ के बाद मुझे एक शुद्धवादी होने का कारण बन जाएगा। अगर ऐसा मौजूद है तो मैं इसे लिखने के लिए किसी भी तरह से एक अच्छी तरह से सराहना करता हूं।

public string GetColumnValue(string columnName) 
     { 
      object value = item[columnName]; 

      if (value == null) 
       return string.Empty; 

      if (value.GetType() == typeof(string)) 
      { 
       return (string)value; 
      } 
      else if (value.GetType() == typeof(double)) 
      { 
       return ((double)value).ToString(); 
      } 
      ... 
     } 

उत्तर

8

यदि सब आप कर रहे हैं सी # के बहुरूपी प्रकृति के कारण, ToString बुला रहा है, ToString सही कार्यान्वयन फोन करेगा, भले ही आपके पास वस्तु के लिए एक संदर्भ है।

उदा .:

var d=DateTime.Now; 
object od=d; 
Console.WriteLine(od.ToString()); 
Console.WriteLine(d.ToString()); //same as previous line 
+1

यह बुनियादी प्रकार के लिए काम करता है, लेकिन कस्टम प्रकार के लिए अच्छी तरह से काम नहीं हो सकता है - क्या मद में वापस किया जा सकता [columnName] ... –

+0

रीड, आपको एक उदाहरण देता कर सकते हैं पर निर्भर करता है? – spender

+0

मैंने ईमानदारी से नहीं सोचा था कि यह काम करेगा। तो तर्क के लिए, आप किसी विशेष प्रकार के विरासत वृक्ष पर एक टॉस्ट्रिंग कार्यान्वयन को स्पष्ट रूप से कैसे कॉल कर सकते हैं? –

1

स्वीकार्य प्रकार की अपनी सूची के आधार पर आप Convert.ToString और/या IConvertable interface उपयोग करने पर विचार कर सकते हैं।

यह आपको एक शॉट में सबसे प्राचीन प्रकारों को संभालने की अनुमति देगा।

हालांकि, आपको अभी भी अपनी शून्य जांच को संभालने की आवश्यकता होगी।

0

आप क्यों नहीं कर सकते हैं। टॉस्ट्रिंग() value पर। ToString() ऑब्जेक्ट से विरासत में मिला है? उचित प्रकार के लिए। ToString() आगे बढ़ने के लिए विरासत श्रृंखला कहा जाएगा।

+0

हालांकि, अभी भी शून्य जांच की आवश्यकता है। –

1

संपादित

टेस्ट कोड यहाँ हैं अगर कोई रुचि रखता है: http://gist.github.com/raw/305787/dc5349d9f6fa37ee5d621b43ec92dade60fe1c8d/ToStringTests.cs

आप नीचे मेरी मूल जवाब मिल जाएगा। किसी ने इंगित किया कि आपके पास एक प्रकार हो सकता है जिसमें आपके पास ToString() नहीं है (क्योंकि यह ऑब्जेक्ट का उपयोग करता है या श्रृंखला में कुछ ऊपर होता है)। सबसे अच्छा तरीका है 3.0+ में इस संभाल करने के लिए इस तरह की एक विस्तार विधि के साथ है:

public static class ToStringExpander 
    { 
     public static string MyToString (this Object x) 
     { 
      return x.ToString(); 
     } 

     public static string MyToString (this mytype x) 
     { 
      return "This is the to string of mytype!"; 
     } 
    } 

अब MyType GetColumnValue के साथ काम करेंगे नीचे आप MyToString()

मूल पोस्ट को toString() परिवर्तित करते हैं

यह वही करेगा जो आप चाहते हैं।

public string GetColumnValue(string columnName) 
    { 
     object value = item[columnName]; 

     if (value == null) 
      return string.Empty; 

     return object.ToString(); 
    } 

या यदि आप पुराने स्कूल देखना चाहते हैं:

निश्चित रूप से
public string GetColumnValue(string columnName) 
    { 
     return (item[columnName] == null ? string.Empty : item[columnName].ToString()); 
    } 

सच पुराने स्कूल एक #define मैक्रो बनाने के लिए किया जाएगा ...

+1

विधि नाम रिज़ॉल्यूशन नियमों की आवश्यकता होती है कि किसी ऑब्जेक्ट के सदस्य विधियों को प्राथमिकता में किसी भी एक्सटेंशन विधियों में चुना जा सकता है जो दायरे में हो सकते हैं। तो मुझे पूरा यकीन है कि आप जो सुझाव दे रहे हैं वह काम नहीं करेगा। –

+0

हाँ, मैंने अभी इसका परीक्षण किया है, जिस पुस्तक को मैं पढ़ रहा था, वह इस तरह कार्य करेगा जैसा मैंने वर्णन किया था, मैंने जवाब को एक नए समाधान में बदल दिया। – Hogan

0

ToString() एक आभासी विधि है। इसका मतलब है कि उस विधि के लिए कोई भी कॉल रनटाइम पर सही कार्यान्वयन ("सबसे व्युत्पन्न प्रकार") का चयन करेगा। चूंकि सभी प्राथमिक प्रकार सही चीज करने के लिए ToString() ओवरराइड करते हैं, इसलिए किसी भी प्रकार के चर के किसी भी कास्टिंग के लिए कोई कारण नहीं है।

एक आभासी विधि के लिए, चर के प्रकार के सही क्रियान्वयन के चयन में कोई फर्क नहीं पड़ता। सभी महत्वपूर्ण बात यह है कि ऑब्जेक्ट का रनटाइम प्रकार संदर्भित किया जा रहा है।

int x = 10; 
object o = x; 
x.ToString(); 
o.ToString(); 

ToString() के दोनों कॉल एक ही कोड (ऋण unboxing कि object संस्करण में होता है के बाद से int एक मूल्य के प्रकार है) पर अमल होगा।

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