हालांकि अन्य उत्तरों सही हैं, इस अर्थ में कि वे सच और प्रासंगिक बयान देते हैं, यहां भाषा डिजाइन के कुछ सूक्ष्म बिंदु हैं जिन्हें अभी तक व्यक्त नहीं किया गया है। सशर्त ऑपरेटर के वर्तमान डिजाइन में कई अलग-अलग कारक योगदान करते हैं।
सबसे पहले, यह एक स्पष्ट प्रकार के लिए जितना संभव हो उतना अभिव्यक्ति के लिए वांछनीय है जिसे अभिव्यक्ति की सामग्री से पूरी तरह से निर्धारित किया जा सकता है। यह कई कारणों से वांछनीय है। उदाहरण के लिए: यह इंटेलिसेन्स इंजन को बहुत आसान बनाता है। आप x.M(some-expression.
टाइप करते हैं और इंटेलिसेन्स को कुछ अभिव्यक्ति का विश्लेषण करने में सक्षम होना चाहिए, इसके प्रकार का निर्धारण करें, और इंटेलिसेन्स से पहले एक ड्रॉपडाउन उत्पन्न करें, यह पता है कि x.M किस विधि को संदर्भित करता है। IntelliSense यह नहीं जान सकता कि x.M क्या निश्चित रूप से संदर्भित करता है कि एम को सभी तर्कों को तब तक अधिभारित किया जाता है जब तक कि यह सभी तर्कों को नहीं देखता है, लेकिन आपने अभी तक पहले तर्क में टाइप नहीं किया है।
दूसरा, हम सटीक परिदृश्य के कारण "अंदर से बाहर" प्रवाह करने के लिए प्रकार की जानकारी पसंद करते हैं: अधिभार संकल्प। निम्नलिखित पर विचार करें:
void M(object x) {}
void M(int x) {}
void M(string x) {}
...
M(b ? 1 : "hello");
यह क्या करना चाहिए? क्या यह वस्तु अधिभार को कॉल करना चाहिए? क्या इसे कभी-कभी स्ट्रिंग ओवरलोड को कॉल करना चाहिए और कभी-कभी int ओवरलोड को कॉल करना चाहिए? क्या होगा यदि आपके पास एक और ओवरलोड था, तो M(IComparable x)
कहें - आप इसे कब चुनते हैं?
चीजें "दोनों तरीकों से बहती है" टाइप करते समय चीजें बहुत जटिल होती हैं। कह रहा है, "मैं इस वस्तु को प्रकार ऑब्जेक्ट के चर के लिए असाइन कर रहा हूं, इसलिए संकलक को पता होना चाहिए कि ऑब्जेक्ट को चुनने के लिए ठीक है" टाइप नहीं है; यह अक्सर ऐसा होता है कि हम उस वैरिएबल के प्रकार को नहीं जानते हैं जिसे आप असाइन कर रहे हैं क्योंकि हम को समझने की कोशिश करने की प्रक्रिया में हैं। ओवरलोड रिज़ॉल्यूशन वास्तव में पैरामीटर के प्रकारों को काम करने की प्रक्रिया है, जो तर्क हैं कि आप तर्कों के प्रकार से तर्कों को निर्दिष्ट कर रहे हैं। यदि तर्क के प्रकार उन प्रकारों पर निर्भर करते हैं जिन पर उन्हें असाइन किया जा रहा है, तो हमारे तर्क में हमारे पास एक परिपत्र है।
टाइप जानकारी लैम्बडा अभिव्यक्तियों के लिए "दोनों तरीकों का प्रवाह" करती है; कार्यान्वयन ने मुझे कुशलतापूर्वक एक वर्ष का बेहतर हिस्सा लिया। मैंने एक संकलक को डिजाइन करने और कार्यान्वित करने में कुछ कठिनाइयों का वर्णन करने वाले लेखों की एक लंबी श्रृंखला लिखी है जो विश्लेषण कर सकते हैं जहां संदर्भ सूचना के आधार पर जटिल अभिव्यक्तियों में टाइप की जाती है जिसमें अभिव्यक्ति संभवतः उपयोग की जा रही है; भाग एक यहाँ है:
http://blogs.msdn.com/ericlippert/archive/2007/01/10/lambda-expressions-vs-anonymous-methods-part-one.aspx
संभव है कि आप कहते हैं कि "ठीक है, ठीक है, मैं देख रहा हूँ क्यों तथ्य यह है कि मैं विरोध करने संकलक द्वारा सुरक्षित रूप से नहीं किया जा सकता है बताए रहा हूँ, और मैं देख रहा हूँ क्यों इसके लिए आवश्यक है अभिव्यक्ति का एक स्पष्ट प्रकार है, लेकिन अभिव्यक्ति ऑब्जेक्ट का प्रकार क्यों नहीं है, क्योंकि int और स्ट्रिंग दोनों ऑब्जेक्ट में परिवर्तनीय हैं?"यह मुझे मेरे तीसरे बिंदु पर लाता है:
तीसरा, सी # के सूक्ष्म लेकिन लगातार लागू किए गए डिजाइन सिद्धांतों में से एक है" जादू द्वारा प्रकारों का उत्पादन न करें "। जब अभिव्यक्तियों की एक सूची दी जाती है जिसमें से हमें एक निर्धारित करना होगा टाइप करें, हमारे द्वारा निर्धारित प्रकार हमेशा सूची में है। हम कभी भी एक नए प्रकार को जादू नहीं करते हैं और इसे आपके लिए चुनते हैं; आपको जो प्रकार मिलता है वह हमेशा होता है जिसे आपने हमें चुनने के लिए दिया है। अगर आप सबसे अच्छा पाते हैं प्रकारों के एक सेट में टाइप करें, हमें उस प्रकार के सेट में सबसे अच्छा प्रकार मिलता है। सेट {int, string} में, कोई भी सामान्य प्रकार नहीं है, जिस तरह से है, कहें, "पशु, कछुए, स्तनपायी, वालाबी "यह डिज़ाइन निर्णय सशर्त ऑपरेटर पर लागू होता है, अनुमानित एकीकरण परिदृश्य टाइप करने के लिए, अंतर्निहित टाइप किए गए सरणी प्रकारों के अनुमान के लिए, और इसी तरह।
इस डिजाइन के फैसले का कारण यह है कि सामान्य मनुष्यों के लिए यह काम करना आसान हो जाता है कि कंपाइलर किसी भी स्थिति में क्या करने जा रहा है जहां सबसे अच्छा प्रकार निर्धारित किया जाना चाहिए; यदि आप जानते हैं कि एक प्रकार जो सही है, आपको चेहरे पर घूर रहा है, तो इसे चुना जा रहा है, यह जानने के लिए बहुत आसान है कि क्या होने जा रहा है।
यह हमें कई जटिल नियमों को पूरा करने से भी बचाता है कि विवाद होने पर प्रकारों के सेट का सबसे अच्छा सामान्य प्रकार क्या है। मान लीजिए कि आपके पास {Foo, Bar} प्रकार हैं, जहां दोनों वर्ग आईबीएलए लागू करते हैं, और दोनों वर्ग बाज़ से प्राप्त होते हैं। आईबीएलए का सबसे अच्छा आम प्रकार कौन सा है, जो दोनों लागू होते हैं, या बाज़, दोनों का विस्तार होता है? हम इस सवाल का जवाब नहीं देना चाहते हैं; हम इसे पूरी तरह से टालना चाहते हैं।
अंत में, मुझे लगता है कि सी # कंपाइलर वास्तव में कुछ अस्पष्ट मामलों में गलत प्रकार के निर्धारण का दृढ़ संकल्प प्राप्त करता है। इस बारे में मेरा पहला लेख यहाँ है:
http://blogs.msdn.com/ericlippert/archive/2006/05/24/type-inference-woes-part-one.aspx
यह वास्तव में संकलक यह सही करता है और कल्पना गलत है कि विवाद-योग्य है; कार्यान्वयन डिजाइन मेरी राय में spec'd डिजाइन से बेहतर है।
वैसे भी, यह टर्नरी ऑपरेटर के इस विशेष पहलू के डिजाइन के लिए केवल कुछ कारण हैं। उदाहरण के लिए, यहां अन्य सूक्ष्मताएं हैं, सीएलआर सत्यापनकर्ता कैसे निर्धारित करता है कि ब्रांचिंग पथों का एक निर्धारित सेट सभी संभावित पथों में स्टैक पर सही प्रकार को छोड़ने की गारंटी देता है या नहीं। चर्चा करते हुए कि विस्तार से मुझे बहुत दूर ले जाएगा।
क्या आप अपने प्रश्न के शीर्षक में टाइपो को ठीक कर सकते हैं, धन्यवाद। मेरे पास इसे संपादित करने के लिए पर्याप्त प्रतिष्ठा नहीं है। –
फिक्स –
के लिए धन्यवाद आपके दूसरे उदाहरण में आप लिख सकते हैं: value = subscription आईडी ?? DBNull.Value; –