2012-08-24 14 views
11

मेरे पास आधार वर्ग Aक्यों अतिभारित विधियाँ उदाहरण विधि की तुलना में कम प्राथमिकता दी जाती है

public class A 
{ 
    public virtual void Method(A parameter) 
    { 
     Console.WriteLine(MethodBase.GetCurrentMethod()); 
    } 
    public virtual void Method(B parameter) 
    { 
     Console.WriteLine(MethodBase.GetCurrentMethod()); 
    } 
} 

Inhereted B

public class B : A 
{ 
    public virtual void Method(object parameter) 
    { 
     Console.WriteLine(MethodBase.GetCurrentMethod()); 
    } 

    public override void Method(A parameter) 
    { 
     Console.WriteLine(MethodBase.GetCurrentMethod()); 
    } 

    public override void Method(B parameter) 
    { 
     Console.WriteLine(MethodBase.GetCurrentMethod()); 
    } 
} 

विस्तार विधि के साथ स्टेटिक वर्ग S

public static class S 
{ 
    public static void Method(this B instance, B parameter) 
    { 
     Console.WriteLine(MethodBase.GetCurrentMethod()); 
    } 
} 

उदाहरण हम उदाहरण बनानेटाइप करेंऔर Method पर हमला करते हैं, हम उम्मीद करते हैं कि यह public override void Method(B parameter) वास्तविक परिणाम public virtual void Method(object parameter) होगा।

var b = new B(); 
b.Method(new B()); // B.Method (Object parameter) Why??? 

क्यों संकलक अधिक उपयुक्त विधि का चयन नहीं करता ??? UPD और यह विस्तार विधि क्यों नहीं है?

+3

'बी' नेस्टेड नहीं है लेकिन विरासत में मिला है। –

+0

@ हेनक होल्टरमैन धन्यवाद – user854301

+0

यदि ऑब्जेक्ट में समान नाम से विधि है तो एक्सटेंशन विधि को कॉल नहीं किया जाता है। यह पुराना कोड तोड़ने से बचने के लिए है जहां पुरानी विधि को कॉल करना है, न कि नया एक्सटेंशन एक। – Ankush

उत्तर

10

क्यों संकलक अधिक उपयुक्त विधि का चयन नहीं करता है?

यह जब एक उम्मीदवार विधि की खोज, जब तक कि भाषा विनिर्देश, जहां किसी भी उम्मीदवार के तरीकों मूल रूप से एक आधार वर्ग (अधिक अगर वे एक व्युत्पन्न वर्ग में अधिरोहित कर रहे हैं) में घोषित की नियमों का पालन नहीं है, इसलिए ध्यान नहीं दिया जाता व्युत्पन्न वर्ग में कोई लागू विधियां नहीं होती हैं, जिस बिंदु पर खोज बेस क्लास आदि तक जाती है।

यह designed to avoid the "brittle base class" problem है, लेकिन मुझे लगता है कि व्युत्पन्न में ओवरराइड किए जाने वाले तरीके के चेहरे पर निगलना मुश्किल है कक्षा।

सी # 4 विनिर्देश के प्रासंगिक बिट 7.4 जो इस के साथ समाप्त होता है,:

इंटरफेस में प्रकार पैरामीटर और इंटरफेस, और सदस्य लुकअप के अलावा अन्य प्रकार के सदस्य लुकअप कि सख्ती से एकल विरासत हैं (विरासत श्रृंखला में प्रत्येक इंटरफ़ेस में बिल्कुल शून्य या एक प्रत्यक्ष आधार इंटरफ़ेस है), लुकअप नियमों का प्रभाव केवल व्युत्पन्न सदस्य समान नाम या हस्ताक्षर वाले आधार सदस्यों को छुपाते हैं।

संपादित

: के बारे में विस्तार तरीकों ...

और क्यों यह विस्तार तरीका नहीं है?

कल्पना की धारा 7.6.5.2 से

:

रूपों में से एक की एक विधि मंगलाचरण (§7.5.5.1) में

expr . identifier () 
expr . identifier (args) 
expr . identifier <typeargs> () 
expr . identifier <typeargs> (args) 

अगर मंगलाचरण की सामान्य प्रक्रिया कोई लागू विधि नहीं मिलती है, एक विस्तार विधि आमंत्रण के रूप में निर्माण को संसाधित करने का प्रयास किया जाता है

तो एक विस्तार विधि केवल मूल रूप से अंतिम उपाय के रूप में उपयोग की जाती है।

+0

मुझे लगता है कि प्रश्न यह है कि एक्सटेंशन विधि के बजाय विरासत विधि को कॉल करने वाला कोड क्यों है, लेकिन यह कहना मुश्किल है? – podiluska

+0

@ पॉडिलुस्का: मुझे लगता है कि विस्तार विधि एक लाल हेरिंग है। ओपी को यह कहने की उम्मीद नहीं है ... –

+0

यह भी दिलचस्प है कि विस्तार विधि को क्यों नहीं कहा जाता है। – user854301

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