8

तो मैंने Eric Lippert's 'Constraints are not part of the signature' पढ़ा, और अब मैं समझता हूं कि स्पेक निर्दिष्ट करता है कि ओवरलोड रिज़ॉल्यूशन के बाद उस प्रकार की बाधाओं की जांच की जाती है, लेकिन मुझे अभी भी यह स्पष्ट नहीं है कि यह मामला क्यों होना चाहिए। नीचे एरिक के उदाहरण है:विधि हस्ताक्षर का बाधा हिस्सा क्यों नहीं हैं?

यह संकलन नहीं करता है के लिए अधिभार संकल्प है क्योंकि: Foo(new Giraffe()) infers कि Foo<Giraffe> सबसे अच्छा अधिभार मुकाबला नहीं है लेकिन फिर प्रकार की कमी असफल और एक संकलन समय त्रुटि फेंक दिया है। एरिक के शब्दों में:

सिद्धांत यहां अधिभार संकल्प (और विधि प्रकार अनुमान) तर्कों की सूची और औपचारिक मानकों की प्रत्येक उम्मीदवार विधि की सूची के बीच सबसे अच्छा संभव मिलान ढूंढता है। यही है, वे उम्मीदवार विधि के हस्ताक्षर को देखते हैं।

टाइप बाधाएं हस्ताक्षर का हिस्सा नहीं हैं, लेकिन वे क्यों नहीं हो सकते हैं? कुछ परिदृश्य क्या हैं जहां हस्ताक्षर के प्रकार की बाधाओं पर विचार करना बुरा विचार है? क्या यह कार्यान्वित करना मुश्किल या असंभव है? मैं वकालत नहीं कर रहा हूं कि यदि सबसे अच्छा चुने गए ओवरलोड को कॉल करने के लिए असंभव कारण है तो चुपचाप दूसरे सर्वश्रेष्ठ पर फॉलबैक; मैं उससे नफरत करता हूं। मैं बस यह समझने की कोशिश कर रहा हूं कि सर्वश्रेष्ठ अधिभार के चयन को प्रभावित करने के लिए टाइप बाधाओं का उपयोग क्यों नहीं किया जा सकता है।

मैं कल्पना कर रहा है कि आंतरिक रूप से सी # संकलक में, अधिभार संकल्प प्रयोजनों के लिए ही (यह स्थायी रूप से विधि पुनर्लेखन नहीं करता है), निम्नलिखित:

:

static void Foo<T>(T t) where T : Reptile { } 

में तब्दील हो जाता है

static void Foo(Reptile t) { } 

आप औपचारिक पैरामीटर सूची में प्रकार की बाधाओं को "खींचें" क्यों नहीं कर सकते? यह किसी भी बुरे तरीके से हस्ताक्षर कैसे बदलता है? मुझे लगता है कि यह केवल हस्ताक्षर को मजबूत करता है। फिर Foo<Reptile> कभी अधिभार उम्मीदवार के रूप में नहीं माना जाएगा।

संपादित करें 2: कोई आश्चर्य नहीं कि मेरा प्रश्न इतना भ्रमित था। मैंने एरिक के ब्लॉग को ठीक से नहीं पढ़ा और मैंने गलत उदाहरण उद्धृत किया। मैंने उदाहरण में संपादित किया है जो मुझे लगता है कि अधिक उपयुक्त है। मैंने शीर्षक को और अधिक विशिष्ट होने के लिए भी बदल दिया है। यह सवाल उतना आसान नहीं लगता जितना मैंने पहली बार कल्पना की थी, शायद मुझे कुछ महत्वपूर्ण अवधारणा याद आ रही है। मुझे कम यकीन है कि यह स्टैक ओवरफ्लो सामग्री है, इस प्रश्न/चर्चा को कहीं और स्थानांतरित करने के लिए यह सबसे अच्छा हो सकता है।

+1

आपके प्रश्न के शीर्ष पर उद्धृत इगुआनास के बारे में थोड़ा सा उद्देश्य ऐसी परिस्थिति को चित्रित करना था जहां टाइप धारणा * खाते में बाधा डालती है, अर्थात् टी में टी पर बाधा, और इसलिए ओवरलोड रिज़ॉल्यूशन अंततः चुनता है इस उदाहरण में * गैर सामान्य * विधि। क्या आप निश्चित रूप से इस आलेख से पूछने के लिए उद्धृत करने का इरादा रखते हैं कि लेख का प्रासंगिक बिट है? प्रश्न का शेष तार्किक रूप से इसका पालन नहीं करता है। –

+1

मुझे लगता है कि आप यह पूछने का इरादा रखते हैं कि ऐसा क्यों है कि जब टाइप अनुमान * सफल होता है * लेकिन एक प्रकार का अनुमान लगाता है जो विधि प्रकार पैरामीटर * पर बाधा का उल्लंघन करता है, तो विकल्प होने पर ओवरलोड रिज़ॉल्यूशन विफल क्यों होता है। मुझे यह सवाल बहुत भ्रमित कर रहा है, लेकिन फिर, यह विनिर्देश का एक भ्रमित हिस्सा है। –

+0

आप सही हैं। मैंने आपके ब्लॉग को गलत तरीके से पढ़ा और गलत उदाहरण का इस्तेमाल किया। कोई आश्चर्य नहीं कि मेरा सवाल इतना उलझन में था। मैंने अपने प्रश्न को जितना संभव हो उतना स्पष्ट करने की कोशिश की है; मैं यह देखने के लिए कि क्या मैं इस विषय पर अपनी समझ में सुधार कर सकता हूं, मैं आपके कुछ अन्य ब्लॉग पोस्टों के माध्यम से भी पढ़ रहा हूं। – Daryl

उत्तर

4

सी # संकलक विधि हस्ताक्षर के रूप में भाग के रूप में प्रकार की कमी पर विचार नहीं है क्योंकि वे CLR हस्ताक्षर विधि का हिस्सा नहीं हैं है। अगर ओवरलोड रिज़ॉल्यूशन अलग-अलग भाषाओं के लिए अलग-अलग काम करता है तो यह विनाशकारी होगा (मुख्य रूप से गतिशील बाध्यकारी के कारण जो रनटाइम पर हो सकता है और एक भाषा से दूसरे भाषा में अलग नहीं होना चाहिए, या अन्य सभी हेल्स ढीले हो जाएंगे)।

यह क्यों तय किया गया था कि सीएलआर के लिए यह बाधाएं विधि हस्ताक्षर का हिस्सा नहीं होंगी, एक और प्रश्न है, और मैं केवल इसके बारे में बीमार सूचित अनुमान लगा सकता हूं। मैं लोगों को इस जवाब में जवाब दूंगा।

+0

लेकिन यह सवाल उठाता है कि "सी # का हिस्सा क्यों नहीं है, यह सीएलआर का हिस्सा क्यों नहीं है" ... ओवरलोड रिज़ॉल्यूशन के समर्थन में एक प्रमुख समस्या है जो प्रकार की बाधाओं को मानती है (मेरा जवाब देखें) । –

+0

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

0

यदि T कई बाधाओं से मेल खाता है, तो आप एक अस्पष्टता बनाते हैं जिसे स्वचालित रूप से हल नहीं किया जा सकता है। उदाहरण के लिए आप बाधा

where T : ISecond

अब आप टी एक वर्ग है कि IFirst और ISecond दोनों को लागू करता है होना चाहता हूँ के साथ बाधा

where T : IFirst

और एक अन्य के साथ एक सामान्य वर्ग की है।

कंक्रीट कोड उदाहरण:

public interface IFirst 
{ 
    void F(); 
} 

public interface ISecond 
{ 
    void S(); 
} 

// Should the compiler pick this "overload"? 
public class My<T> where T : IFirst 
{ 
} 

// Or this one? 
public class My<T> where T : ISecond 
{ 
} 

public class Foo : IFirst, ISecond 
{ 
    public void Bar() 
    { 
     My<Foo> myFoo = new My<Foo>(); 
    } 

    public void F() { } 
    public void S() { } 
} 
+0

.. यह नाम टकराव का कारण बनता है; मेरे प्रश्न में त्रुटि संकलक के कारण होती है जो यह नहीं जानती कि विधि कॉल के लिए कौन सी विधि अधिभार चुनती है: 'बार (नया इगुना(), शून्य) '। मैं शायद धीमा हो रहा हूं, लेकिन मुझे अभी तक इन दोनों के बीच कनेक्शन नहीं दिख रहा है। मैं आपके उदाहरण का थोड़ा और अध्ययन करने जा रहा हूं .. – Daryl

+4

@EricJ आप जेनिक्स का उपयोग किए बिना विधि अस्पष्टता भी पैदा कर सकते हैं- एक ही स्थिति तब होगी जब विधि के दो अधिभार क्रमशः 'IFirst' और' ISecond' लिया गया था, और आपने कोशिश की 'Foo' प्रकार के तर्क के साथ कॉल करने के लिए कौन सी विधि को हल करने के लिए। मुझे नहीं लगता कि यही कारण है कि सी # टीम ने इसे विधि हस्ताक्षर का हिस्सा न लेने का फैसला किया। –

+0

@ क्रिसशैन हम्म, लेकिन अगर आपके पास विधि कॉल IFirst और ISecond लेने के लिए अस्पष्टता है तो संकलक त्रुटि देगा और आप इच्छित इंटरफ़ेस को पैरामीटर कास्टिंग करके समस्या को ठीक कर सकते हैं। यदि सामान्य बाधाएं विधि हस्ताक्षर का हिस्सा थीं तो आपको कॉल साइट पर विभिन्न बाधाओं के बीच चयन करने के लिए एक वाक्यविन्यास की आवश्यकता होगी, और लाइब्रेरी की सामान्य बाधाओं में किए गए किसी भी बदलाव का मतलब होगा कि कॉलिंग कोड को काम जारी रखने के लिए पुन: संकलित करना होगा जो मुझे लगता है कि आदर्श से कम है । –

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