विचित्र के रूप में यह लग सकता है, यह बस सी # भाषा कल्पना से नियमों का पालन कर रहा है।
खंड From.३.४ से:
प्रपत्र x op y का संचालन, जहाँ op एक अधिभार बाइनरी ऑपरेटर है, x एक प्रकार X की अभिव्यक्ति है, और y एक प्रकार Y की अभिव्यक्ति है, इस प्रकार संसाधित किया जाता है:
- ऑपरेशन ऑपरेटर ऑप (x, y) के लिए X और Y द्वारा प्रदान किए गए उम्मीदवार उपयोगकर्ता-परिभाषित ऑपरेटरों का सेट निर्धारित किया जाता है। सेट में एक्स द्वारा प्रदान किए गए उम्मीदवार ऑपरेटरों के संघ और वाई द्वारा प्रदान किए गए उम्मीदवार ऑपरेटर होते हैं, प्रत्येक .37.3.5 के नियमों का उपयोग करके निर्धारित होता है। यदि X और Y एक ही प्रकार हैं, या यदि X और Y एक सामान्य आधार प्रकार से प्राप्त हुए हैं, तो साझा उम्मीदवार ऑपरेटर केवल एक बार संयुक्त रूप में होते हैं।
- यदि उम्मीदवार उपयोगकर्ता निर्धारित ऑपरेटरों का सेट खाली नहीं है, तो यह ऑपरेशन के लिए उम्मीदवार ऑपरेटरों का सेट बन जाता है। अन्यथा, पूर्वनिर्धारित बाइनरी ऑपरेटर ऑप इम्प्लीमेंटेशन, जिसमें उनके उठाए गए फॉर्म शामिल हैं, ऑपरेशन के लिए उम्मीदवार ऑपरेटरों का सेट बन जाते हैं। किसी दिए गए ऑपरेटर के पूर्वनिर्धारित कार्यान्वयन ऑपरेटर के विवरण में निर्दिष्ट होते हैं ()7.8 §7.12 के माध्यम से)।
- .37.5.3 के अधिभार संकल्प नियम तर्क सूची (x, y) के संबंध में सर्वश्रेष्ठ ऑपरेटर का चयन करने के लिए उम्मीदवार ऑपरेटरों के सेट पर लागू होते हैं, और यह ऑपरेटर अधिभार संकल्प प्रक्रिया का परिणाम बन जाता है। यदि ओवरलोड रिज़ॉल्यूशन किसी एकल सर्वश्रेष्ठ ऑपरेटर का चयन करने में विफल रहता है, तो बाइंडिंग-टाइम त्रुटि उत्पन्न होती है।
तो, चलिए इसके माध्यम से बारी बारी से चलते हैं।
X यहां अशक्त प्रकार है - या नहीं एक प्रकार है, यदि आप इस तरह से सोचना चाहते हैं। यह कोई उम्मीदवार उपलब्ध नहीं करा रहा है। Y है bool
, जो किसी भी उपयोगकर्ता-परिभाषित +
ऑपरेटरों को प्रदान नहीं करता है । तो पहला कदम कोई उपयोगकर्ता-परिभाषित ऑपरेटर नहीं पाता है।
संकलक फिर पूर्वनिर्धारित बाइनरी ऑपरेटर + कार्यान्वयन और उनके उठाए गए रूपों को देखते हुए, दूसरे बुलेट बिंदु पर जाता है। ये कल्पना की धारा 7.8.4 में सूचीबद्ध हैं।
यदि आप उन पूर्वनिर्धारित ऑपरेटरों के माध्यम से देखते हैं, तो केवल एक ही लागू होता है string operator +(string x, object y)
। तो उम्मीदवार सेट में एक ही प्रविष्टि है। यह अंतिम गोली बिंदु को बहुत सरल बनाता है ... अधिभार संकल्प उस ऑपरेटर को चुनता है, जो एक समग्र अभिव्यक्ति प्रकार देता है string
।
एक दिलचस्प बात यह है कि यह तब भी होगा जब अन्य उपयोगकर्ता-परिभाषित ऑपरेटर बिना किसी प्रकार के उपलब्ध हैं। उदाहरण के लिए:
// Foo defined Foo operator+(Foo foo, bool b)
Foo f = null;
Foo g = f + true;
यह ठीक है, लेकिन यह एक अशक्त शाब्दिक के लिए उपयोग नहीं किया जाता है, क्योंकि संकलक को देखने के लिए नहीं पता है Foo
। यह केवल विचार करना जानता है string
क्योंकि यह पूर्वनिर्धारित ऑपरेटर स्पष्ट रूप से कल्पना में सूचीबद्ध है। (वास्तव में, यह स्ट्रिंग प्रकार द्वारा परिभाषित ऑपरेटर नहीं है ... 1 ) इसका मतलब है कि यह संकलन करने में विफल रहेगा:
// Error: Cannot implicitly convert type 'string' to 'Foo'
Foo f = null + true;
अन्य दूसरे-ऑपरेंड प्रकार कुछ अन्य ऑपरेटरों का उपयोग करेंगे, निश्चित रूप से:
var x = null + 0; // x is Nullable<int>
var y = null + 0L; // y is Nullable<long>
var z = null + DayOfWeek.Sunday; // z is Nullable<DayOfWeek>
1 आप सोच रहे होंगे कि स्ट्रिंग + ऑपरेटर क्यों नहीं है। यह एक उचित सवाल है, और मैं केवल उत्तर पर अनुमान लगा रहा हूं , लेकिन इस अभिव्यक्ति पर विचार करें:
string x = a + b + c + d;
यदि string
सी # संकलक में कोई विशेष आवरण नहीं था, तो यह प्रभावी रूप से समाप्त हो जाएगा:
string tmp0 = (a + b);
string tmp1 = tmp0 + c;
string x = tmp1 + d;
तो यह दो अनावश्यक मध्यवर्ती तार पैदा करता है। हालाँकि, संकलक के भीतर विशेष समर्थन होने के कारण, यह वास्तव में उपरोक्त संकलन करने में सक्षम है:
string x = string.Concat(a, b, c, d);
जो बिल्कुल सही लंबाई का एक ही तार बना सकता है, जिससे एक बार में ही सारा डेटा कॉपी हो जाता है। अच्छा लगा।