2010-10-26 11 views
13

मुझे हाल ही में आश्चर्य हुआ कि संकलक इंटरफ़ेस संदर्भों की तुलना करने के बारे में सख्ती से सख्त नहीं है और मुझे आश्चर्य है कि यह इस तरह क्यों काम करता है।असंबद्ध सी # इंटरफ़ेस संदर्भों को संकलक त्रुटि के बिना क्यों तुलना की जा सकती है?

इस कोड पर विचार करें:

class Program 
{ 
    interface I1 {} 
    interface I2 {} 
    class C1 : I1 {} 
    class C2 : I2 {} 

    static void Main(string[] args) 
    { 
     C1 c1 = new C1(); 
     C2 c2 = new C2(); 

     I1 i1 = c1; 
     I2 i2 = c2; 

     bool x = c1 == c2; 
     bool y = i1 == i2; 
    } 
} 

संकलक का कहना है कि मैं c1 == c2 तुलना नहीं कर सकते, जो इस प्रकार है। प्रकार पूरी तरह से असंबंधित हैं। फिर भी, यह मुझे i1 == i2 की तुलना करने की अनुमति देता है। मैं संकलन-समय विफलता के साथ यहां त्रुटि करने की उम्मीद करता हूं लेकिन मुझे यह जानकर आश्चर्य हुआ कि आप किसी भी इंटरफ़ेस की तुलना किसी अन्य से कर सकते हैं और संकलक कभी शिकायत नहीं करेगा। मैं तुलना कर सकता हूं, उदाहरण के लिए (I1)null == (IDisposable)null और कोई समस्या नहीं है।

इंटरफेस ऑब्जेक्ट्स नहीं हैं? क्या वे एक विशेष प्रकार का संदर्भ हैं? मेरी उम्मीद यह होगी कि == परिणामस्वरूप सीधे संदर्भ तुलना या कंक्रीट क्लास के आभासी बराबर में कॉल होगा।

मुझे क्या याद आ रही है?

+2

जानकारी के लिए, '==' आमतौर पर op_Equality ऑपरेटर से जुड़ा होता है, न कि आभासी बराबर (प्लस संदर्भ तुलना, लेकिन आप पहले से ही इसे कवर करते हैं) –

उत्तर

12

सबसे पहले, ध्यान दें कि हंस विनिर्देश के सही खंड को उद्धृत कर रहा है, लेकिन वह उद्धरण के विनिर्देश का संस्करण एक टाइपो है जो आपके प्रश्न के लिए प्रासंगिक है। सुधारा सी # 4 विनिर्देश का कहना है:

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

(1) दोनों ऑपरेंड एक प्रकार में जाना जाता है के एक मूल्य एक संदर्भ प्रकार हो रहे हैं या शाब्दिक शून्य। इसके अलावा, स्पष्ट संदर्भ रूपांतरण अन्य ऑपरेंड के प्रकार के लिए या तो ऑपरेंड के प्रकार से मौजूद है।

(2) एक ऑपरेंड टी प्रकार का मान है जहां टी एक प्रकार-पैरामीटर है और अन्य ऑपरेंड शाब्दिक शून्य है। इसके अलावा टी में प्रकार की बाधा नहीं है।

जब तक इनमें से कोई भी स्थितियां सत्य नहीं हैं, बाध्यकारी समय त्रुटि होती है।

यह आपके अवलोकन को बताता है। किसी भी दो इंटरफेस के बीच एक स्पष्ट संदर्भ रूपांतरण है क्योंकि दो अलग-अलग इंटरफेस के किसी भी दो उदाहरण उसी ऑब्जेक्ट का संदर्भ दे सकते हैं। एक वर्ग सी 3 हो सकता है जो I1 और I2 दोनों लागू करता है, और आप सी 3 के समान उदाहरण की संदर्भ तुलना कर सकते हैं, एक I1 में परिवर्तित हो गया है और दूसरा I2 में परिवर्तित हो सकता है।

+0

यहां बहुत सारे अच्छे उत्तर हैं, लेकिन आपका सबसे अधिक मेरे प्रश्न का उत्तर देता है। धन्यवाद। – scobi

13

मुझे लगता है यह इस तरह से किया गया था, क्योंकि आप एक प्रकार दोनों इंटरफेस और इस मामले के लिए इस तरह तुलना उपयोगी हो सकता है विरासत में हो सकता है:

interface I1 {} 
interface I2 {} 
class C1 : I1, I2 {} 

तो में पहले मामले संकलक निश्चित रूप से जानता है कि वस्तुओं रहे हैं अलग लेकिन दूसरे मामले में वे नहीं हो सकता है।

+0

स्पष्टीकरण मेरे लिए काम करता है +1 – gn22

0

मेरी उम्मीद यह होगी कि एक == परिणामस्वरूप सीधे संदर्भ तुलना या कंक्रीट क्लास के वर्चुअल इक्विल्स में कॉल का परिणाम होगा।

यह सच है, लेकिन संकलक इसे नहीं जानता है। यह रन-टाइम पर निर्धारित किया जाएगा।

4

यह सी # भाषा विशिष्टता में बहुत अच्छी तरह से वर्णन किया गया है, अध्याय 7.9.6 "संदर्भ प्रकार समानता ऑपरेटरों":

पूर्वनिर्धारित संदर्भ प्रकार समानता ऑपरेटरों हैं:

bool ऑपरेटर == (ऑब्जेक्ट एक्स, ऑब्जेक्ट वाई);
बूल ऑपरेटर! = (ऑब्जेक्ट एक्स, ऑब्जेक्ट वाई);

ऑपरेटर समानता या गैर-समानता के लिए दो संदर्भ की तुलना करने के परिणाम लौटाते हैं।

के बाद से पूर्वनिर्धारित संदर्भ प्रकार समानता ऑपरेटरों के प्रकार वस्तु ऑपरेंड स्वीकार करते हैं, वे सभी प्रकार कि लागू ऑपरेटर == और ऑपरेटर नहीं घोषित करते हैं पर लागू होते हैं! = सदस्य हैं। इसके विपरीत, किसी भी लागू उपयोगकर्ता द्वारा परिभाषित समानता ऑपरेटरों प्रभावी रूप से पूर्वनिर्धारित संदर्भ प्रकार समानता ऑपरेटरों को प्रभावी रूप से छुपाएं।
दोनों ऑपरेंड • संदर्भ प्रकार मान या शाब्दिक अशक्त हैं:

पूर्वनिर्धारित संदर्भ प्रकार समानता ऑपरेटरों में से एक निम्नलिखित की आवश्यकता है। इसके अलावा, एक मानक निहित रूपांतरण (§6.3.1) से दूसरे ऑपरेंड के के प्रकार के लिए ऑपरेंड के प्रकार से मौजूद है।
• एक ऑपरेंड प्रकार टी का मान है जहां टी टाइप-पैरामीटर है और अन्य ऑपरेंड शाब्दिक शून्य है। इसके अलावा टी में मान प्रकार बाधा नहीं है।

इनमें से कोई भी शर्तों में से कोई भी सत्य नहीं है, एक संकलन-समय त्रुटि होती है। इन नियमों के उल्लेखनीय निहितार्थ हैं:
• यह दो संदर्भों कि संकलन समय पर अलग अलग हो जाते हैं की तुलना करने के पूर्वनिर्धारित संदर्भ प्रकार समानता ऑपरेटरों का उपयोग करने के लिए एक संकलन समय त्रुटि है। उदाहरण के लिए, यदि ऑपरेंड के संकलन समय प्रकार दो वर्ग टाइप ए और बी, और अगर न एक हैं और न ही बी अन्य से निकला है, तो यह असंभव दो ऑपरेंड को संदर्भित करने के लिए एक ही होगा वस्तु। इस प्रकार, ऑपरेशन संकलन-समय त्रुटि माना जाता है।

अंतिम अनुच्छेद यह है कि आपको त्रुटि क्यों मिलती है।

+2

ध्यान दें कि आप सी # 3.0 से उद्धरण दे रहे हैं विनिर्देश, जिसमें एक टाइपो शामिल है जो इस प्रश्न के लिए प्रासंगिक है। उपरोक्त "निहित" को "स्पष्ट" पढ़ना चाहिए। –

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