2011-02-07 30 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 
    { 

    } 

çıktısı: AAAYöntem aşırı yükleme ve polimorfizmi

çıkışı olacağını bu yüzden, her nasılsa yöntem aşırı yüklenmesini kullanmak mümkün mü: ABC? C# 4 kullanıyorsanız

cevap

12

Dinamik yazarak kullanabilirsiniz:

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

statik yazarak içinde, aşırı yük çözünürlük değil yürütülmesi sırasında, derleme zamanında gerçekleştirilir. uygulanması için

ya aşırı yerine arasında ağır basan kullanın veya yukarıdaki gibi dinamik yazarak kullanmak zorunda, karar zamanda seçilecek.

+1

Derleme zamanında aşırı yük çözünürlüğü yapılmasına rağmen "B b" ve "C c" üzerinde neden "A a" seçilir? – Sandeep

+1

@Sandeep: "Ana" içindeki "a" değişkeninin derleme zamanı türü yalnızca A olduğundan, çünkü liste bir "Liste ". Bu nedenle, (yalnızca) Render (a) 'sadece * * Render (A a)' yı seçin. –

2

Bir temel (soyut) sınıfından türeyen bir B C yapın, bu sınıfta bir yöntem oluşturun ve her A B C'de düzgün bir şekilde geçersiz kılın. Render(a)'u aramak yerine, a.Render() numaralı telefonu arayın, bu polimorfizmin çalışması gereken yoldur.

13

şu o tür içinde bir tür ile çalışırken biz davranışını kontrol hile yapmak gerektiğini:

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(); 
} 

Ve o kadar katkı olmak bir tür tanımlanan davranışı istiyorsanız onun ebeveyn, o zaman örneğin, kendi mantığı yürüttükten sonra baz uygulanan yöntemini çağırın:

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

başka yolu da bu visitor pattern ile gerçekleştirmek için: Eğer gibi bir şey başarmak için izin verir iki yönlü yöntemi çağıran sistemi kullanılarak polimorfizmi:

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); 
    } 
} 

Bu yaklaşıma avantajı etkili her tür doğru aşırı yük kesinlikle yazılan this içten Render geçerek tarafından çağrılan sağlar (polimorfizm elde olanak sağlamasıdır) Kendi türünüze ait olmayan mantığı korurken (ör. görsel işleme mantığı).