5

(शीर्षक में "उपयोगकर्ता परिभाषित" इस तथ्य को संदर्भित करता है कि TimeSpan और DateTime के अतिरिक्त और घटाव सी # मानक का हिस्सा नहीं हैं। वे हैं बीसीएल में परिभाषित किया गया।)उपयोगकर्ता परिभाषित ऑपरेटरों के साथ नग्न नल शाब्दिक का उपयोग करते समय उत्सुक अधिभार संकल्प

हटाए गए ऑपरेटरों के साथ घूमने योग्य TimeSpan और DateTime मानों पर चारों ओर बजाना, मैंने निम्नलिखित कोड लिखा था। ध्यान दें कि ढांचा TimeSpan और DateTime पर विभिन्न परिचालन प्रदान करता है।

एक सममित (और कम्यूटिव) अतिरिक्त है जहां आप दो TimeSpan लेते हैं और योग TimeSpan वापस लेते हैं। इस जोड़ का "उलटा" दो TimeSpan का घटाव TimeSpan उपज है।

तो फिर वहाँ इसके अलावा, विषम, जहां आपको एक DateTime (बाएं संकार्य) और एक TimeSpan (सही संकार्य) ले एक DateTime का उत्पादन करने का एक और प्रकार है। इस ऑपरेशन की असमानता के कारण, इसमें दो "प्रकार" उलटा है: एक जहां आप अंतर प्राप्त करने के लिए एक दूसरे से दो DateTime घटाते हैं, और एक जहां आपके पास DateTime है और परिणाम DateTime परिणाम देने के लिए इसे TimeSpan से घटाएं ।

static void Main() 
{ 
    DateTime? n_dt = new DateTime(2012, 12, 25); 
    TimeSpan? n_ts = TimeSpan.FromDays(62.0); 

    var a = n_dt + n_ts; // OK 
    var b = n_ts + n_ts; // OK 

    var c = null + n_dt; // OK, string concatenation! Type of expression is String 
    var d = null + n_ts; // OK, compiler prefers TS+TS, not DT+TS 
    var e = n_dt + null; // OK, DT+TS 
    var f = n_ts + null; // OK, TS+TS 
    var g = null + null; // error, type of expression is undetermined 

    var h = n_dt - n_dt; // OK 
    var i = n_dt - n_ts; // OK 
    var j = n_ts - n_ts; // OK 

    var k = null - n_dt; // OK, DT-DT 
    var l = null - n_ts; // compiler prefers TS-TS, not DT-TS 
    var m = n_dt - null; // error, compiler won't choose between DT-DT amd DT-TS, type of expression is undetermined 
    var n = n_ts - null; // OK, TS-TS 
    var o = null - null; // OK, integer subtraction! Type of expression is Nullable<Int32> 

    // illegal: 
//var p = n_dt + n_dt; 
//var q = n_ts + n_dt; 
//var r = n_ts - n_dt; 
} 

कुछ सवाल स्वाभाविक रूप से उत्पन्न होते हैं।

यह थोड़ा अजीब है कि o अनुमति दी है और देता है एक int? (क्यों तरीका है? द्वारा एक long? नहीं), जबकि g अनुमति नहीं है। क्या यह कल्पना में है? साथ ही, यह थोड़ा अजीब बात है कि "असंभव" c स्ट्रिंग concatenation द्वारा हल किया गया है। स्पष्ट रूप से संकलक निर्णय लेता है कि c में (string)null है। दूसरी तरफ DateTime पर स्पष्ट प्रकार object की अभिव्यक्ति जोड़ना, संकलित नहीं होगा।

लेकिन मेरा मुख्य सवाल यह है: क्यों संकलक d और l के लिए एक अधिभार चयन कर सकते हैं, लेकिन m साथ यह अस्पष्टता के बारे में शिकायत?

+3

अब तक यहां तक ​​कि अजीब चीज var o = null-null है; –

+0

'c' स्ट्रिंग कॉन्सटेनेशन का उपयोग करता है क्योंकि भाषा ऑपरेटरों को उपयोगकर्ता परिभाषित ऑपरेटरों पर प्राथमिकता दी जाती है, और यह अभिव्यक्ति 'ऑपरेटर + (स्ट्रिंग, ऑब्जेक्ट)' के स्ट्रिंग कॉन्सटेनेशन ऑपरेटर से मेल खाती है। निश्चित रूप से 'डी' का सवाल उठाता है, हालांकि उस तर्क के अनुसार जो स्ट्रिंग कॉन्सटेनेशन को हल करना चाहिए। – Servy

+0

@ डेवबीश सहमत हुए। मुझे लगता है कि यह int/long – Servy

उत्तर

0

कारण है कि m साथ, दो संभव संचालन एक ही प्रकार के अंदर परिभाषित, अर्थात् System.DateTime हैं लगता है। उनके बीच चयन करने का कोई तरीका नहीं है।

दूसरी ओर, d और l साथ, एक आपरेशन System.TimeSpan में परिभाषित किया गया है, और अन्य एक System.DateTime में परिभाषित किया गया है। लेकिन d और l की तर्ज पर, हम TimeSpan देखते हैं, लेकिन DateTime का कोई उल्लेख नहीं है कि d और l के असाइनमेंट में कभी भी टाइप करें। यह संकलक की तरह लगता है, फिर केवल System.TimeSpan प्रकार में परिभाषित ऑपरेटरों के माध्यम से खोजता है, और अन्य सभी प्रकारों में परिभाषित उपयोगकर्ता परिभाषित ऑपरेटरों के माध्यम से खोजना भूल जाता है (जो खोज के लिए बहुत से प्रकार होंगे)। इस तरह, d और l के संकल्प के दौरान, संकलक DateTime प्रकार के अंदर परिभाषित ऑपरेटरों को कभी भी खोज नहीं करता है।

+1

सी # spec के सेक्शन 7.3.4 देखें, क्योंकि यह प्रासंगिक प्रतीत होता है और इस उत्तर की पुष्टि करने के लिए। – Servy

+0

"वैसे" वास्तव में। – phoog

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