2010-09-28 6 views
7

एक उदाहरण होगा:रचनाकारों के बजाय अंतर्निहित/स्पष्ट रूपांतरणों का उपयोग करने का क्या कारण है?

XNamespace ns = "my namespace" 

क्यों ?: नहीं

XNamespace ns = new XNamespace ("my namespace") 

अंतर्निहित/स्पष्ट convertions बजाय निर्माताओं की का उपयोग कर के पीछे विचार यह क्या है? सुविधा?

क्या इसके लिए कोई दिशानिर्देश है?

उत्तर

9

सुविधा?

अधिक या कम, हाँ। इस मामले पर विचार करें कि जब आपके पास संख्या-जैसी वस्तु है (कहें, Complex) जिस पर आप गणना करते हैं। जाहिर है, कोड लिखना जैसे:

Complex result = c1 * new Complex(2) + new Complex(32); 

बहुत परेशान और पढ़ने में मुश्किल है। लागू रूपांतरण यहां सहायता करते हैं (एक विकल्प इस उदाहरण में ऑपरेटर ओवरलोड होगा, लेकिन इससे बहुत सारे अधिभार होंगे)।

क्या इसके लिए कोई दिशानिर्देश है?

बाद से वे समस्याओं छिपा सकते हैं, संभव के रूप में कुछ निहित रूपांतरण प्रदान करें। लागू रूपांतरण उसी राशि से स्पष्टीकरण को कम करता है जिसके द्वारा वे दृढ़ता बढ़ाते हैं। कभी-कभी यह अच्छा होता है, लेकिन कभी-कभी नहीं।

मैं यह सबसे अच्छा ऐसी मेरी उदाहरण में संख्या की तरह वस्तुओं से ऊपर के रूप में बहुत समान प्रकार, के लिए अंतर्निहित रूपांतरण प्रतिबंधित करने के लिए लगता है: एक int अनिवार्य है-एक Complex (एक गणितीय दृष्टि से, भले ही यह द्वारा मॉडल नहीं कर रहा है विरासत), इसलिए एक अंतर्निहित रूपांतरण समझ में आता है।

वीबी में, एक अंतर्निहित रूपांतरण "Widening" कहा जाता है (जैसा कि Narrowing, जो explicit है के खिलाफ) हैं और इस यह अच्छी तरह से वर्णन करता है: कोई जानकारी नहीं रूपांतरण के दौरान खो दिया है।

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

मेरे Complex उदाहरण पर विचार करें। हम अक्सर इस्तेमाल परिसर संख्या के लिए मूल्यों को कैश करने के लिए कर सकते हैं:

Class Complex { 
    // Rest of implementation. 

    private static Complex[] cache = new[] { 
     new Complex(-1), new Complex(0), new Complex(1) }; 

    public implicit operator Complex(int value) { 
     if (value >= -1 && value <= 1) 
      return cache[value]; 
     else 
      return new Complex(value); 
    } 
} 
बेशक

, कि क्या यह सूक्ष्म अनुकूलन प्रभावी है एक और सवाल है।

+0

धन्यवाद, आप ऑपरेटर ओवरलोड के लिए ऐसा कैसे करेंगे जो जटिल प्रकार की मदद करेगा? आपको int प्रकार को संपादित करने में सक्षम होना चाहिए, है ना? –

+0

@ जोन: नहीं, चूंकि आप दोनों दिशाओं में ऑपरेटर को कार्यान्वित कर सकते हैं: * * अपने कस्टम प्रकार और * से * अपने कस्टम प्रकार से। मेरे उदाहरण में, बस 'कॉम्प्लेक्स' ऑपरेटर 'निहित ऑपरेटर कॉम्प्लेक्स (इंट वैल्यू) लागू करें। –

+0

धन्यवाद मैं इसे अभी प्राप्त करता हूं। –

3

अंतर्निहित/स्पष्ट रूपांतरण के उपयोग सुविधा और एक है कि कई प्रोग्रामिंग दिशा निर्देशों सुझाव है कि आप स्पष्ट ConvertToXXX तरीकों के पक्ष में से बचने का मुद्दा है।

समस्याओं में से एक था निहित ऑपरेटर के निहित/स्पष्ट रूपांतरणों के आगे ओवरलोड कार्यों का उपयोग।यह वस्तु के पदानुक्रम

  • में एक अलग प्रकार/इंटरफेस के माध्यम से एक ही वस्तु देखने एक नए प्रकार कुल मिलाकर
  • दुर्भाग्य से सी # पहले से ही बाद करता है करने के लिए वस्तु coverting

    • के दोहरे उद्देश्य देता है अन्य क्षेत्रों में (प्राइमेटिव्स और मुक्केबाजी के साथ)।

    1

    व्यक्तिगत रूप से, मैं रूपांतरण (color = "red" कह तरह color = Colors.Red यह सूचित करते हैं)

    मैं नए ऑपरेटर का उपयोग का उपयोग करते हैं मुझे पता है कि आरएचएस एक वर्ग के एक स्थिर सदस्य में परिवर्तित हो सकता है जब मैं वास्तव में एक बनाने के लिए करना चाहते हैं नया उदाहरण

    2

    दो वर्गों को एक दूसरे से परिवर्तनीय होना चाहिए, लेकिन वे एक आधार वर्ग है कि इस व्यवहार स्वचालित रूप से अनुमति देता है के लिए एक इंटरफेस का हिस्सा नहीं है तो आप रूपांतरण का प्रयोग करेंगे। लागू रूपांतरण कभी डेटा हानि की संभावना नहीं होनी चाहिए; उन्हें अक्सर "चौड़ा" रूपांतरण माना जाता है। उदाहरण के लिए, int को long में परिवर्तित करना एक व्यापक रूपांतरण है, और रूपांतरण में अंतर्निहित कोई समस्या नहीं है। स्पष्ट रूपांतरण में डेटा हानि की संभावना शामिल हो सकती है; long इसके मूल्य के आधार पर int पर परिवर्तनीय हो सकता है या नहीं भी हो सकता है।

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

    +0

    धारणा है कि "अंतर्निहित रूपांतरण डेटा हानि का कारण नहीं बनना चाहिए" भाषा लोकप्रिय है, लेकिन मुझे लगता है कि एक बेहतर धारणा "* राउंड-ट्रिप * अंतर्निहित रूपांतरण डेटा हानि का कारण नहीं बनना चाहिए"। यदि 'सिंपल टाइप' एक 'जटिल टाइप' का प्रतिनिधित्व करता है जहां "जटिल" गुण सभी डिफ़ॉल्ट मानों से मेल खाते हैं, तो रूपांतरणों को चौड़ा करने के लिए केवल 'सरल टाइप' से 'जटिल टाइप' तक ही अनुमति दी जानी चाहिए, लेकिन यदि यह 'जटिल टाइप' का प्रतिनिधित्व करता है जहां जटिल गुणों के मान अज्ञात हैं , अंतर्निहित रूपांतरण, यदि कुछ भी हो, केवल दूसरे तरीके की अनुमति दी जानी चाहिए। – supercat

    5

    जैसे साधारण प्रकार के साथ अंतर्निहित रूपांतरण का उपयोग के रूप में XName, है मैं तरीकों बुला में विश्वास करते हैं, सुविधा के पीछे के कारणों में से एक।

    उदाहरण के लिए, आप डेटा निकालने पर

    var info = root.Elements ("user").Element ("info").Value; 
    

    सादगी लिख सकते हैं क्या LINQ के बारे में है, और अगर हम लिखना पड़ा

    var info = root.Elements (new XName ("user")).Element (new XName ("info")).Value; 
    

    भी सरल प्रश्नों के लिए, LINQ पूरी तरह से किया जाएगा जटिल लोगों के लिए लायक है?

    यहां एक और महत्वपूर्ण मुद्दा यह है कि XNames परमाणु हैं। MSDN देखें:

    XName वस्तुओं atomized जाने की गारंटी है; यानी, यदि दो XName ऑब्जेक्ट्स में बिल्कुल वही नामस्थान है और बिल्कुल वही स्थानीय नाम है, तो वे उसी उदाहरण को साझा करेंगे। इस उद्देश्य के लिए समानता और तुलना ऑपरेटर भी स्पष्ट रूप से प्रदान किए जाते हैं।

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

    आप निर्माता में atomization प्रदान नहीं कर सकते, लेकिन एक रूपांतरण निर्धारित करते समय आपको पूल से इसी वस्तु लेने और इसे वापस के रूप में अगर यह एक नया उदाहरण थे करने के लिए अनुमति देता है।

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

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