2013-04-12 8 views
13

मैंने सोचा कि जिस विधि को बुलाया जा रहा है उसे रनटाइम का फैसला किया गया है, या क्या मुझे कुछ याद आया है? नमूना कोड:ओवरलोडेड विधि क्यों नहीं बुलाई जा रही है?

class Program 
{ 
    static void Main(string[] args) 
    { 
     var magic = new MagicClass(); 
     magic.DoStuff(new ImplA()); 
     magic.DoStuff(new ImplB()); 
     Console.ReadLine(); 
    } 
} 
class MagicClass 
{ 
    internal void DoStuff<T>(T input) where T : SomeBase 
    { 
     HiThere(input); 
    } 

    void HiThere(SomeBase input) 
    { 
     Console.WriteLine("Base impl"); 
    } 

    void HiThere(ImplA input) 
    { 
     Console.WriteLine("ImplA"); 
    } 

    void HiThere(ImplB input) 
    { 
     Console.WriteLine("ImplB"); 
    } 
} 

abstract class SomeBase 
{ 

} 
class ImplA : SomeBase{} 
class ImplB : SomeBase{} 

मैंने सोचा कि मैं मिलेगा:

ImplA 
ImplB 
आउटपुट के रूप में

लेकिन यह Base impl प्रिंट करता है। क्या इनपुट कास्टिंग किए बिना अधिभारित विधि प्राप्त करने के लिए मैं कुछ भी कर सकता हूं?

+2

यहां एक सुंदर सभ्य स्पष्टीकरण है: http://csharpindepth.com/Articles/General/Overloading.aspx –

उत्तर

18

ओवरलोड को संकलक द्वारा चुना जाता है। कॉल यहाँ के लिए:

internal void DoStuff<T>(T input) where T : SomeBase 
{ 
    HiThere(input); 
} 

यह, SomeBase साथ एक चुन लेगा यह संकलन समय पर है, क्योंकि इतना ही है।

जो आप शायद सबसे अधिक चाहते हैं ओवरराइड है। इसका मतलब यह है अलग तर्क SomeBase का वारिस में डाल दिया है:

abstract class SomeBase 
{ 
    abstract string Name { get; } 
} 
class ImplA : SomeBase{ override string Name { get { return "ImplA"; } } } 
class ImplB : SomeBase{ override string Name { get { return "ImplB"; } } } 

void HiThere(SomeBase input) 
{ 
    Console.WriteLine(input.Name); 
} 
+2

एक और संभावना यह है कि वह [डबल प्रेषण'] (http: //en.wikipedia) करना चाहता है। संगठन/विकी/डबल_डिस्पाच) या ['विज़िटर पैटर्न'] (http://en.wikipedia.org/wiki/Visitor_pattern) का उपयोग करें। –

+6

या 'गतिशील' का उपयोग: 'हायटेयर ((गतिशील) इनपुट);' यह ओवरलोड रिज़ॉल्यूशन को रनटाइम पर ले जाता है जहां सटीक प्रकार का 'इनपुट' ज्ञात है। –

+0

@ डैनियल हिल्गार्थ: शायद यह डबल-प्रेषण का सबसे अच्छा संभव कार्यान्वयन है। :) –

4

Overloads संकलन के दौरान चुने गए हैं।
रनटाइम के दौरान ओवरराइड का चयन किया जाता है।

यहां, कंपाइलर्स केवल जानता है कि टी को SomeBase पर असाइन किया जा सकता है, लेकिन कुछ भी नहीं। असल में, अगर यह आपके द्वारा अपेक्षित काम करता है, तो आप where T : SomeBase भाग को पूरी तरह से छोड़ने में सक्षम होंगे। आपको इसकी आवश्यकता होने का कारण यह है कि कंपाइलर को उस जानकारी को जानने की आवश्यकता है ताकि यह सुनिश्चित किया जा सके कि प्रदान की गई वस्तु पर क्या कहा जा सकता है।

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