2016-03-20 19 views
0

Hayvanların yaptıklarını ve hayvanların nasıl göründüğünü modellemeye çalışıyorum ve her bir hayvanın kodunu ve eylemlerin kodu da ayrı ayrı tutmak istiyorum. Bunu C# ile nasıl modelleyebilirim?Endişelerin ayrılması ve polimorfik tasarım

Bu ideal olacaktır: Eğer doğru anlamak Paint değil Paint(Cat) veya Paint(Dog) gibi Paint(Animal) olarak tanımlanır eğer

using System.Collections.Generic; 

class PaintingAnimals { 
    class Animal {} 
    class Cat : Animal {} 
    class Dog : Animal {} 

    static void Paint(Cat cat) { System.Console.WriteLine("Cat"); } 
    static void Paint(Dog dog) { System.Console.WriteLine("Dog"); } 
    static void Paint(Animal animal) { System.Console.WriteLine("Animal"); } 

    public static void Main() { 
    var animals = new List<Animal> {new Cat(), new Dog()}; 

    foreach (var animal in animals) { 
     Paint(animal); // Always prints "Animal" not "Cat" or "Dog" 
    } 
    } 
} 

Ancak, bu kodu yalnızca derlemek ve bu nedenle ben benim kod bölemezsiniz Her bir hayvan, Köpekler ve Kediler gibi farklı fonksiyonlara farklı şekilde boyanacaktır. uygun gördüğü şekilde her somut Hayvan sınıf Boya yöntemi uygulayacak

static void Main() { 
    var animals = new List<Animal> {new Cat(), new Dog()}; 

    foreach (var animal in animals) { 
    animal.Paint(); 
    } 
} 

: Eğer parametre olarak hayvanla bir yöntemi çağırmak değil, ama daha ziyade hayvan AÇIK bir yöntem aramak istediğiniz ne

+2

Bunu yapmanın pek çok yolu var ... Seçenek olarak göz atın [ziyaretçi kalıbı] (https://en.wikipedia.org/wiki/Visitor_pattern) - olasılıkla 'Piant ((dinamik) hayvan) ile uygulanır 've Paint (Cat)' ın tam seti ... geçersiz kılar. –

+0

"Her iki nesne için aynı kod" ne demek istediğini anlamıyorsunuz, Boya işlevinizi gösterebilir misiniz? –

+0

@AlexeiLevenkov Ziyaretçi kalıbı! Faydalı işaretçi, teşekkürler. – user12341234

cevap

0

.

+1

Ne yazık ki, bu çözüm benim 'Boya' kodumu diğer kodumla aynı yerde tutmamı zorlaştırıyor ... Hepsi yan Cat/Köpek sınıfı. – user12341234

+0

'Paint 'gerçekten her bir sınıfın içine ait. Aksi takdirde, her bir farklı olası Hayvana hitap etmek için "global" Paint yönteminde büyüyen bir "if" veya "select" ifadesine ihtiyacınız olacaktır. –

+0

Büyüyen bir ifade, tek bir çözümdür, ancak modüllerin sıkı bir şekilde bağlanmasını zorlar. Diğer dillerde dinamik sevk veya parametrik polimorfizm işe yarayabilecek alternatiflerdir. C# 'da dev bir anahtara ihtiyacı olmayan başka bir yol var mı diye merak ediyordum. – user12341234

0

AlexeiLevenkov önerisi @ araştırdıktan sonra, ben ne istediğini yapmak için aşağıdaki kodu buldum:

using System.Collections.Generic; 

class PaintingAnimals { 
    class Animal {} 
    class Cat : Animal {} 
    class Dog : Animal {} 

    static void Paint(Cat cat) { System.Console.WriteLine("Cat"); } 
    static void Paint(Dog dog) { System.Console.WriteLine("Dog"); } 
    static void Paint(Animal animal) { System.Console.WriteLine("Animal"); } 

    public static void Main() { 
    var animals = new List<Animal> {new Cat(), new Dog()}; 

    foreach (dynamic animal in animals) { // Uses "dynamic", not "var" 
     Paint(animal); // Print's "Cat" and "Dog" respectively, not "Animal" 
    } 
    } 
} 

Burada anahtar her öğe türünü değiştirir foreach döngüsünde dynamic kullanımı olduğunu sırasıyla Animal ila Cat ve Dog.