5

को देखते हुए तुलना तरीकों में से दो कार्यान्वयन:सशर्त ऑपरेटर और तुलना प्रतिनिधि

// compares by Key... 
private static int CompareByKey(KeyValuePair<int, string> x, KeyValuePair<int, string> y) 

{ 
    return x.Key.CompareTo(y.Key); 
} 

// compares by Value... 
private static int CompareByValue(KeyValuePair<int, string> x, KeyValuePair<int, string> y) 
{ 
    return x.Value.CompareTo(y.Value); 
} 

क्यों नहीं होगा निम्नलिखित सशर्त ऑपरेटर कोड ब्लॉक संकलन:

Comparison<KeyValuePair<int, string>> sortMethod; 
sortMethod = isSortByActualValue ? CompareByKey : CompareByValue; 

संकलक त्रुटि: "सशर्त अभिव्यक्ति का प्रकार नहीं कर सकते निर्धारित किया जाए क्योंकि 'विधि समूह' और 'विधि समूह' '

के बीच कोई अंतर्निहित रूपांतरण नहीं है, हालांकि, समकक्ष कोड ब्लॉक अगर- else d ओ इ एस कोई समस्या आती है नहीं:

Comparison<KeyValuePair<int, string>> sortMethod; 
if (isSortByActualValue) 
    sortMethod = CompareByKey; 
else 
    sortMethod = CompareByValue; 

(ऊपर दोनों कार्य में सब अच्छा)

तो सशर्त ऑपरेटर करता है, अगर मैं तुलना प्रतिनिधि डाली:

Comparison<KeyValuePair<int, string>> sortMethod; 
sortMethod = isSortByActualValue ? (Comparison<KeyValuePair<int, string>>) CompareByKey : CompareByValue; 

(में सब अच्छा उपरोक्त असाइनमेंट, जब कास्ट किया गया था, भले ही कास्टिंग केवल वास्तविक भाग पर था)

+2

तुलना कैसे करें ByAcutalValue और तुलना ByDisplayValue परिभाषित? आप केवल तुलनाबीकी और तुलना ByValue की परिभाषा दिखाते हैं। –

+0

मेरी पोस्टिंग में कोड स्निपेट स्पष्टता के लिए संपादित किया गया था। मुझे एहसास नहीं हुआ कि मैंने केवल आंशिक रूप से नाम (तरीकों का) बदल दिया है। धन्यवाद एरिक, मैंने तुलना ByAckualValue से तुलना करने के लिए सभी संदर्भों को अद्यतन किया है (और तुलना ByDisplayValue तुलना ByValue)। – Arun

उत्तर

7

थ त्रुटि विधि वास्तव में यह सब कहती है लेकिन यह काफी सहज नहीं है। यदि आप विधि का आविष्कार किए बिना विधि नाम का उपयोग करते हैं, तो आप विधि समूह को प्रबंधित कर रहे हैं। "समूह", क्योंकि एक विधि अधिभारित किया जा सकता है और नाम किसी भी ओवरलोडेड विधियों को इंगित कर सकता है।

अब, विधि समूह मेल खाने वाले हस्ताक्षर वाले प्रतिनिधि को निहित रूप से परिवर्तनीय हैं, यही कारण है कि if में आपका असाइनमेंट काम करता है।

अभी तक, बहुत अच्छा है। हालांकि, सशर्त ऑपरेटर ?: को एक सामान्य प्रकार को कम करने की आवश्यकता है जिसके लिए इसके दूसरे और तीसरे तर्कों को पूरी तरह से परिवर्तित किया जा सकता है, और यह इसके लिए सभी रूपांतरणों पर विचार नहीं करता है (इसमें विविध समस्याएं होंगी)। यह केवल यह दिखता है कि दोनों तर्कों का एक ही प्रकार है, या कोई एक दूसरे में पूरी तरह से परिवर्तनीय है या नहीं।

यह मामला यहां नहीं है: हालांकि दोनों तर्क विधि समूह हैं, वे वास्तव में अलग-अलग विशिष्ट समूहों वाले विधि समूह हैं, और आप एक विधि समूह को दूसरे में परिवर्तित नहीं कर सकते हैं। भले ही दोनों आसानी से एक प्रतिनिधि में परिवर्तित हो सकते हैं, संकलक इस उपयोग को रोकता है।

ही, अन्य प्रकार के लिए सच है वैसे:

object = someBool ? "" : New List<Integer>(); 

भी एक ही कारण के लिए संकलित करने के लिए, विफल रहता है। और फिर, हम इस स्पष्ट रूप से एक आम आधार प्रकार के तर्क के दोनों कास्टिंग द्वारा संकलन बना सकते हैं:

object = someBool ? (object) "" : New List<Integer>(); 
+1

+1, लेकिन मैं बदल सकता हूं "अपने दूसरे और तीसरे तर्क के प्रकार को कम करने की जरूरत है" को "एक सामान्य प्रकार को कम करने की आवश्यकता है जिसके लिए इसके दूसरे और तीसरे तर्कों को पूरी तरह से परिवर्तित किया जा सकता है" – phoog

+0

तो क्यों नहीं है'SortByActualValue ? तुलना ByKey: तुलना ByKey 'संकलन? क्या वे एक ही विधि समूह नहीं हैं? – svick

+0

@svick विधि समूह के बावजूद विधि समूह से विधि समूह में कोई रूपांतरण मौजूद नहीं है। मुझे यह स्पष्ट होना चाहिए था, और यह एक विशेष मामला है क्योंकि किसी सामान्य प्रकार में इस रूपांतरण की कमी नहीं होती है। मुझे नहीं पता कि यह सी # विनिर्देश में ठीक से कैसे कहा गया है। –

3

आप अपने CompareByKey की तरह एक अभिव्यक्ति है, तो यह किसी भी विशिष्ट नेट प्रकार नहीं है, लेकिन है एक विशेष प्रकार "विधि समूह"। ऐसा इसलिए है क्योंकि आपके पास CompareByKey नामक कई विधियां हो सकती हैं और यह स्पष्ट नहीं है कि आप कौन सी चाहते हैं (और यह ठीक वही काम करता है भले ही आपके पास केवल एक विधि हो)। साथ ही, यह स्पष्ट नहीं है कि आप किस प्रतिनिधि प्रकार चाहते हैं, उदा। Comparison<KeyValuePair<int, string>> या Func<KeyValuePair<int, string>, int>

विधि समूहों के साथ आप क्या कर सकते हैं? आप उन्हें एक प्रतिनिधि (new Comparison<KeyValuePair<int, string>>(CompareByKey)) स्पष्ट रूप से बनाने के लिए उपयोग कर सकते हैं और वे प्रतिनिधियों को भी स्पष्ट रूप से परिवर्तनीय हैं। यही कारण है कि आपका if संस्करण काम करता है।

तो, आपको अपनी समस्या से क्या करना है? जब आपके पास सशर्त ऑपरेटर होता है, तो कंपाइलर को पूरी अभिव्यक्ति के प्रकार को समझना पड़ता है और यह उस वैरिएबल के प्रकार का उपयोग नहीं कर सकता है जिसे आप असाइन करते हैं (यह नहीं है कि सी # में अनुमान कैसे काम करता है)। और चूंकि दोनों अभिव्यक्ति विधि समूह हैं और विधि समूहों को अलग-अलग प्रकार के रूप में माना जाता है, जिनमें एक दूसरे के बीच कोई अंतर्निहित रूपांतरण नहीं होता है, संपूर्ण अभिव्यक्ति का प्रकार निर्धारित नहीं किया जा सकता है। यही कारण है कि आपको त्रुटि मिलती है।

आपको पहले से ही एक फिक्स मिल गया है: या तो सशर्त ऑपरेटर का उपयोग न करें या एक कलाकार (या प्रतिनिधि कन्स्ट्रक्टर) का उपयोग करके स्पष्ट रूप से ऑपरेटरों में से किसी एक प्रकार का निर्दिष्ट न करें।

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