关注点分离和多态设计

时间:2016-03-20 02:20:05

标签: c#

让我们说我试图模拟动物做什么以及动物看起来如何,我想保持每只动物的代码分开,动作/看起来的代码也是分开的。如何在C#中对此进行建模?

这是理想的:

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"
    }
  }
}

但是,如果我理解正确,只有Paint被定义为Paint(Animal)而不是Paint(Cat)Paint(Dog)时,此代码才会被编译,因此我可以&#39;将每只动物的代码分成不同的功能,以便狗和猫的绘画方式不同。

2 个答案:

答案 0 :(得分:0)

你想要做的不是用动物作为参数调用方法,而是调用动物的方法:

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

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

每个具体的Animal类都会在它认为合适时实现Paint方法。

答案 1 :(得分:0)

在调查了@ AlexeiLevenkov的建议后,我发现以下代码可以做我想要的事情:

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"
    }
  }
}

此处的关键是在foreach循环中使用dynamic,它会将每个元素的类型分别从Animal更改为CatDog