2015-04-29 3 views
8

मैं एक struct मिल गया है:< and > ऑपरेटरों का उपयोग करते समय क्या निहित रूपांतरण समर्थित हैं?

public struct Decibel 
{ 
    public readonly double Value; 

    public Decibel (double value) 
    { 
     Value = value; 
    } 

    public static implicit operator Decibel (double decibels) 
    { 
     return new Decibel (decibels); 
    } 

    public static implicit operator double (Decibel decibels) 
    { 
     return decibels.Value; 
    } 
} 

और अब मैं कर सकते हैं:

bool x = new Decibel (0) < new Decibel (1); 

ऐसा लगता है संकलक बहुत चालाक double को कन्वर्ट करने के लिए है, और फिर डबल्स के लिए < ऑपरेटर का उपयोग करें?

मेरे पास struct नाम Duration था, जो TimeSpan लपेट रहा था। TimeSpan के लिए Duration पर इसका अनुमान था, लेकिन < और > ऑपरेटर इसके लिए काम नहीं कर रहे हैं।

क्या सी # केवल आदिम प्रकारों के बीच रूपांतरण को पहचानता है?

+0

वहाँ एरिक Lippert यहां से संबंधित जानकारी है: http://stackoverflow.com/a/8529811/106159 –

+0

'implicit' रूपांतरण यह बहुत आसान बनाने के

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

+0

@ हेंकहोल्टरमैन: मुझे पता है, मैं इसे सावधानीपूर्वक उपयोग करने की कोशिश कर रहा हूं :) – zgnilec

उत्तर

3

सबसे पहले ध्यान दें कि सी # अधिकतम प्रकार के एक अंतर्निहित उपयोगकर्ता परिभाषित रूपांतरण को प्रकारों के बीच अनुमति देगा।

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

हालांकि जब आप Duration के दो उदाहरणों की तुलना करते हैं, तो संकलक को एकल अंतर्निहित रूपांतरण नहीं मिल सकता है, जिसका उपयोग तुलना करने के लिए किया जा सकता है। कंपाइलर किसी भी प्रकार के उपयोगकर्ता द्वारा परिभाषित तुलना ऑपरेटर को किसी भी प्रकार के लिए नहीं मानता है जिस पर प्रकार को रूपांतरित रूप से परिवर्तित किया जा सकता है। यह केवल उन प्रकारों के लिए अंतर्निहित तुलना ऑपरेटर की तलाश करेगा जिनके प्रकार को पूर्ण रूप से परिवर्तित किया जा सकता है।

इसलिए संकलक TimeSpan पर अंतर्निहित रूपांतरण का उपयोग नहीं करेगा, भले ही TimeSpan उपयोगकर्ता द्वारा परिभाषित तुलना ऑपरेटर प्रदान करता है जो सैद्धांतिक रूप से उपयोग किया जा सकता है।

भी ध्यान रखें कि भले ही TimeSpan वर्ग double को एक अंतर्निहित रूपांतरण प्रदान की है, संकलक अभी भी उसका उपयोग नहीं होता है, क्योंकि यह केवल निहित रूपांतरण की श्रृंखला में ज़्यादा से ज़्यादा एक अंतर्निहित उपयोगकर्ता परिभाषित रूपांतरण पर विचार करेगी।

दूसरे शब्दों में, यह देखते हुए इन structs:

public struct Number 
{ 
    public readonly double Value; 

    public Number(double value) 
    { 
     Value = value; 
    } 

    public static implicit operator Number(double duration) 
    { 
     return new Number(duration); 
    } 

    public static implicit operator double(Number number) 
    { 
     return number.Value; 
    } 
} 

public struct NumberWrapper 
{ 
    public readonly Number Value; 

    public NumberWrapper(Number value) 
    { 
     Value = value; 
    } 

    public static implicit operator NumberWrapper(Number duration) 
    { 
     return new NumberWrapper(duration); 
    } 

    public static implicit operator Number(NumberWrapper number) 
    { 
     return number.Value; 
    } 
} 

इस कोड को संकलित कर देगा:

bool x = new Number(1) < new Number(2); 

और निश्चित रूप से इतना होगा इस:

Number n1 = new NumberWrapper(1); 
Number n2 = new NumberWrapper(2); 
bool z = n1 < n2; 

लेकिन यह नहीं होगा :

bool y = new NumberWrapper(1) < new NumberWrapper(2); 

क्योंकि NumberWrapper किसी भी प्रकार के निहित रूपांतरण नहीं है जो < का समर्थन करता है बिना किसी भी निहित रूपांतरण के।

ध्यान दें कि सभी आदिम संख्यात्मक और गणना प्रकार (जैसे चार, लघु, int, लंबा, फ्लोट, डबल, दशमलव, enum) अंतर्निहित तुलना ऑपरेटर प्रदान करते हैं। अन्य सभी प्रकार केवल उपयोगकर्ता द्वारा परिभाषित तुलना ऑपरेटर प्रदान कर सकते हैं।

public static bool operator < (MyType lhs, MyType rhs) ... 
+0

शायद आपको इसे स्पष्ट करने के लिए "उपयोगकर्ता द्वारा परिभाषित तुलना ऑपरेटर" और "अंतर्निहित तुलना ऑपरेटर" के बीच अंतर को समझाया जाना चाहिए। – Magnus

+0

@ मैग्नस: हाँ, टाइमस्पैन के लिए ऑपरेटर इंटेल बना रहे हैं? या निर्मित प्राचीन प्रकार के ऑपरेटरों हैं? – zgnilec

+0

@zgnilec ऑपरेटर केवल प्राचीन प्रकार के लिए अंतर्निहित हैं (जैसा कि मैंने अपने उत्तर के अंत में रखा है) –

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