2010-01-23 8 views
6

वापस मूल बातें करने के लिए ...कोई भी .NET में मान प्रकारों के बीच "सुरक्षित" रूपांतरणों की जांच कैसे कर सकता है?

संदर्भ प्रकार के लिए, एक ऐसा कर सकते हैं:

 SomeType someObject = firstObject as SomeType; 
     if (someObject == null) 
     { 
      // Handle the situation gracefully 
     } 
     else 
     { 
      // Do stuff 
     } 

मूल्य प्रकारों के लिए, मेरी समझ हम निहित रूपांतरण (कोई डेटा हानि), स्पष्ट रूपांतरण (है कि है डेटा हानि का जोखिम होने पर आवश्यक है), Convert वर्ग (एक "रूपांतरण रैपर" मुझे लगता है) और टाइप-विशिष्ट रूपांतरण (जैसे double x = Double.Parse("2");), लेकिन मुझे उपरोक्त as ऑपरेटर के समान कुछ नहीं मिला है।

तो, मेरे सवाल यह है: ढांचा कुछ विधि/ऑपरेटर/तकनीक के साथ प्रदान करता है इन पंक्तियों के साथ कुछ करने के लिए:

 if (!Convert.CanConvert(someValue, someValueType)) 
     { 
      // Beware! Data loss can occur 
     } 
     else 
     { 
      // No data loss here 
     } 

यदि नहीं, वहाँ किसी को भी एक ठोस दृष्टिकोण ऐसे ही एक निर्माण करने के लिए कर सकते हैं सुझाव CanConvert विधि?

बहुत बहुत धन्यवाद!

संपादित करें (1): उपयोगकर्ता के मामले/समस्या इस प्रकार है: एक कुछ कोड के उपभोक्ता द्वारा पारित देखते हुए (मेरे अन्य स्वयं, लेकिन वह अप्रासंगिक है), (1) की जाँच करें कि कुछ एक नंबर है (काफी आसान) और (2) स्थान कुछ "सबसे छोटे" संख्यात्मक प्रकार में जहां यह डेटा हानि के बिना फिट बैठता है।

कुछ पृष्ठभूमि: मैं जो करने की कोशिश कर रहा हूं उसकी प्रकृति तकनीकी से अधिक गणितीय है: मैं यह देखने की कोशिश कर रहा हूं कि मैं मौजूदा संख्यात्मक प्रकारों को किसी प्रकार के बीजगणितीय पदानुक्रम में कैसे फिट कर सकता हूं Monoid = > समूह => अंगूठी => फ़ील्ड (या इसका सरलीकृत संस्करण)। इस पर काम करते हुए, और यह सुनिश्चित नहीं करते कि, "एक चीज़ दूसरे के लिए प्रेरित हुई" और मैंने खुद को टाइप रूपांतरणों से निपटने के लिए पाया ...

+0

पुन: आपका संपादन - मैं वास्तव में इनलाइन संपीड़न एल्गोरिदम के हिस्से के रूप में ऐसा कुछ करता हूं। मेरी विधि? 'लम्बी' से शुरू करें, इसे 'बाइट.मैक्सवैल्यू' के विरुद्ध तुलना करें, फिर 'शॉर्ट.मैक्सवेल्यू', और फिर 'int.MaxValue', और इसे फिट करने वाले सबसे छोटे को डालें! – Aaronaught

+0

मैं नीचे रोब द्वारा सुझाव के बाद इस तरह के कुछ समान कोशिश कर रहा हूं। वही विचार: प्री-डिफ़ाइंड ऑर्डर के बाद रूपांतरणों का प्रयास करें (मैं गणितीय कारणों के लिए हस्ताक्षरित किसी भी चीज़ से हस्ताक्षरित "छोटा" मानता हूं, भले ही स्मृति-वार यह सत्य न हो)। बीटीडब्लू: क्या आपके पास कोई वेब/ब्लॉग है जहां मैं आपके एल्गोरिदम की जांच कर सकता हूं? –

उत्तर

3

विभिन्न मूल्य प्रकारों पर TryParse विधि के बारे में कैसे?

int x; 

if (int.TryParse(someType.ToString(), out x)) 
    return x; 
+1

हालांकि आपको एक अंतिम समापन माता-पिता की आवश्यकता है। ऐसी एक विधि बनाने के लिए एक दृष्टिकोण की पेशकश के लिए – Lee

+0

+1। –

1

as ऑपरेटर विरासत पर आधारित है, और मूल्य प्रकारों का वारिस नहीं है। आप शायद CanConvert() लिख सकते हैं लेकिन इसे बॉक्सिंग वैल्यूएटिप्स के साथ काम करना होगा, और आप आमतौर पर मुक्केबाजी से बचना चाहते हैं।

तो, संभव: हाँ, वांछनीय: नहीं।

शायद तुम एक यूज़-केस परिदृश्य में जहाँ आप इस का उपयोग करना चाहते हैं और फिर हम विकल्प की सिफारिश कर सकते जोड़ सकते हैं।

पुन: संपादित करें (1)

मुझे आशा है कि आप जानते हैं कि संख्यात्मक प्रकार के प्रणाली ज्यादातर ऐतिहासिक सामान है और बहुत ही तार्किक नियमों का पालन नहीं करता है। उदाहरण के लिए short गणना जैसी कोई चीज़ नहीं है, वे हमेशा कुछ भी करने से पहले int में परिवर्तित हो जाते हैं।

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

+0

ओह हाँ, मुझे लगता है कि कंप्यूटर में संख्याओं के साथ कभी भी काम करने वाले किसी भी व्यक्ति को पता है कि वे बहुत तार्किक नियमों का पालन नहीं करते हैं। तो यहां मैं अपना खुद का निर्माण कर रहा हूं। मेरे घर की गोपनीयता में, ज़ाहिर है ... :-) –

1

Convert.ChangeType पर एक नज़र डालें। आप अपने उद्देश्यों को पूरा करने के लिए इसे हाइजैक कर सकते हैं, हालांकि अपवाद फेंकने और डुप्लिकेट रूपांतरण के कारण यह धीमा हो जाएगा।

+0

धन्यवाद - मैंने पोस्ट करने से पहले इसे चेक किया और मैं सहमत हूं, यह मेरे उद्देश्य के लिए अच्छा नहीं लग रहा है। हालांकि सुझाव के लिए –

+0

+1। –

1

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

तो अपने कोड होगा:

if (firstObject is MyValueType) 
{ 
    MyValueType obj = (MyValueType) firstObject; 
} 
else 
{ 
} 
1

मुझे लगता है कि आप के रूप में ऑपरेटर की बात गलत समझ रहे हैं। ऑपरेटर के रूप में लगभग निम्न कोड के बराबर है:

if (firstObject is SomeType) 
    return (SomeType)firstObject; 
else 
    return null; 

इसलिए विरासत की जांच अधिक है। (जैसे सूची लागू करता है ILI)

मूल्य प्रकार विरासत का समर्थन नहीं करते हैं, और अच्छे कारण के लिए। डबल और इंट 64 दोनों नंबर 1 को पूरी तरह से अलग शिष्टाचार में स्टोर करते हैं।

असल में आप जो चाहते हैं वह एक तरीका है जो आपके लिए निर्धारित करेगा कि कोई संख्या रूपांतरण बेकार है या नहीं। खैर मैं "क्यों?" के साथ काउंटर। हालांकि सीएलआर द्वारा समर्थित कुछ प्रारूप हैं, रूपांतरण नियम आमतौर पर बहुत सरल होते हैं। उदाहरण के लिए Int32 -> डबल लापरवाही है, और "छोटे" से "बड़ा" तक कोई रूपांतरण हानि रहित है, जैसे कि एसबीटी -> Int64।

एक और सवाल यह है कि, आपके उदाहरण में झूठा क्या संकेत देगा? मैं बहुत कम कहूंगा, उदाहरण के लिए:

Convert.CanConvert(123456789.12345F, typeof(Byte)) 

गलत परिणाम क्या है? आपको लगता है कि यह इंट 32 -> सिंगल जैसे मामलों के लिए है, जहां कुछ डेटा खो जाएगा, लेकिन इस मामले में डेटा का एक टन खो जा रहा है, क्योंकि "निकटतम" बाइट का प्रतिनिधित्व 255 है।

यह इनके कारण है दो मुद्दे हैं कि ऐसी कोई विधि नहीं है।

2

हेनक पैसे पर बहुत अधिक है। मैं अपने उत्तर में कुछ जोड़ना चाहता हूं, अगर मैं:

.NET Framework में वैल्यू-टाइप रूपांतरण IConvertible इंटरफ़ेस का उपयोग करके काम करता है। Convert कक्षा इसके सभी तरीकों से इसका उपयोग करती है। यह सी # में अंतर्निहित/स्पष्ट रूपांतरण ऑपरेटरों से बहुत अलग है, जो सिंटैक्टिक चीनी का एक और रूप है।

यदि आप लिखना इस:

public struct Duck 
{ 
    public static implicit operator Goose(Duck d) 
    { 
     ... 
    } 
} 

.नेट फ्रेमवर्क ही है पता नहीं है कि इस मौजूद है। इसे op_implicit के रूप में उत्सर्जित किया गया है और यह संकलित भाषा तक है कि इसका उपयोग कैसे किया जाए। हर एमएसआईएल भाषा वास्तव में इन का समर्थन नहीं करती है। इसलिए इस कोड काम करता है:

Goose g1 = duck; 

इस कोड ऐसा नहीं करता:

Goose g1 = (Goose)Convert.ChangeType(duck, typeof(Goose)); 

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

+0

दिलचस्प सामान। +1। –

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