2011-02-07 12 views
9
class Program 
    { 
     static void Main(string[] args) 
     { 
      List<A> myList = new List<A> {new A(), new B(), new C()}; 

      foreach (var a in myList) 
      { 
       Render(a); 
      } 

      Console.ReadKey(); 
     } 

     private static void Render(A o) 
     { 
      Console.Write("A"); 
     } 

     private static void Render(B b) 
     { 
      Console.Write("B"); 
     } 

     private static void Render(C c) 
     { 
      Console.Write("C"); 
     } 
    } 

    class A 
    { 

    } 

    class B : A 
    { 

    } 

    class C : A 
    { 

    } 

L'output è: AAAMetodo sovraccarico e il polimorfismo

E 'possibile usare in qualche modo overloading dei metodi, in modo che l'output sarà: ABC?

risposta

12

È possibile utilizzare la tipizzazione dinamica se si sta utilizzando C# 4:

foreach (dynamic a in myList) 
{ 
    Render(a); 
} 

All'interno tipizzazione statica, risoluzione di sovraccarico viene eseguita a tempo di compilazione, non è al momento dell'esecuzione.

Per l'attuazione di essere scelto al momento della decisione, hai utilizzare sovrascrivendo invece di sovraccarico, o utilizzare la tipizzazione dinamica come sopra.

+1

Anche se la risoluzione di sovraccarico viene fatto al momento della compilazione perché è "A un" viene scelto over "B B" e "C c". – Sandeep

+1

@Sandeep: poiché il tipo di compilazione della variabile 'a' in' Main' è solo A, perché la lista è una 'Lista '. Quindi 'Render (a)' can * only * seleziona 'Render (A a)'. –

2

Make A B C derivante da un (abstract) classe di base, definiscono in quella classe un metodo Render e override correttamente in ogni A B C. Invece di chiamare Render(a) quindi chiamare a.Render() questo è il modo in cui il polimorfismo dovrebbe funzionare.

13

Quanto segue dovrebbe fare il trucco, dove controllare il comportamento quando si lavora con un tipo all'interno di quel tipo:

class A 
{ 
    public virtual void Render() 
    { 
     Console.WriteLine("A"); 
    } 
} 

class B : A 
{ 
    public override void Render() 
    { 
     Console.WriteLine("B"); 
    } 
} 

class C : A 
{ 
    public override void Render() 
    { 
     Console.WriteLine("C"); 
    } 
} 

static void Main(string[] args) 
{ 
    var myList = new List<A> { new A(), new B(), new C() }; 
    foreach (var a in myList) 
    { 
     a.Render(); 
    } 
    Console.ReadKey(); 
} 

E se si desidera che il comportamento definito di un tipo di essere additivo a quello della sua genitore, quindi chiamare il metodo implementato nella base dopo aver eseguito la propria logica, ad esempio:

class B : A 
{ 
    public override void Render() 
    { 
     Console.WriteLine("B"); 
     base.Render(); 
    } 
} 
6

Un altro modo per farlo è con l'visitor pattern: permette di ottenere qualcosa di simile polimorfismo utilizzando un sistema bidirezionale metodo chiamante:

interface IRenderable 
{ 
    AcceptForRender(Program renderer); 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var p = new Program(); 
     var myList = new List<IRenderable> {new A(), new B(), new C()}; 

     foreach (var a in myList) 
     { 
      a.AcceptForRender(p); 
     } 

     Console.ReadKey(); 
    } 

    public void Render(A o) 
    { 
     Console.Write("A"); 
    } 

    public void Render(B b) 
    { 
     Console.Write("B"); 
    } 

    public void Render(C c) 
    { 
     Console.Write("C"); 
    } 
} 

class A : IRenderable 
{ 
    public void AcceptForRender(Program renderer) 
    { 
     renderer.Render(this); 
    } 
} 

class B : IRenderable 
{ 
    public void AcceptForRender(Program renderer) 
    { 
     renderer.Render(this); 
    } 
} 

class C : IRenderable 
{ 
    public void AcceptForRender(Program renderer) 
    { 
     renderer.Render(this); 
    } 
} 

Il vantaggio di questo approccio è che esso consente di ottenere efficacemente polimorfismo (ogni tipo assicura sovraccarico corretto viene chiamata passando il tipizzata this a Render internamente) mantenendo la logica che non appartiene ai tipi stessi (ad es. logica di rendering visuale).

Problemi correlati