C# 关注点分离与多态设计
比如说,我试图对动物的行为和外观进行建模,我想让每个动物的代码和动作/外观的代码分开。我如何用C#建模 这将是理想的:C# 关注点分离与多态设计,c#,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");
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"
}
}
}
使用System.Collections.Generic;
绘画类动物{
类动物{}
类别猫:动物{}
狗类:动物{}
静态无效绘制(Cat){System.Console.WriteLine(“Cat”);}
静态void Paint(Dog-Dog){System.Console.WriteLine(“Dog”);}
静态虚空绘制(动物){System.Console.WriteLine(“动物”);}
公共静态void Main(){
var animals=新列表{new Cat(),new Dog()};
foreach(动物中的动物变量){
绘画(动物);//总是打印“动物”而不是“猫”或“狗”
}
}
}
但是,如果我理解正确,只有当
Paint
定义为Paint(动物)
,而不是Paint(猫)
或Paint(狗)时,此代码才会编译
因此,我不能将每种动物的代码拆分为不同的函数,这样狗和猫的颜色就会不同。您要做的不是调用以动物为参数的方法,而是调用动物上的方法:
static void Main() {
var animals = new List<Animal> {new Cat(), new Dog()};
foreach (var animal in animals) {
animal.Paint();
}
}
static void Main(){
var animals=新列表{new Cat(),new Dog()};
foreach(动物中的动物变量){
动物漆();
}
}
每一个具体的动物类都将根据自己的意愿实现绘画方法。在研究@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"
}
}
}
使用System.Collections.Generic;
绘画类动物{
类动物{}
类别猫:动物{}
狗类:动物{}
静态无效绘制(Cat){System.Console.WriteLine(“Cat”);}
静态void Paint(Dog-Dog){System.Console.WriteLine(“Dog”);}
静态虚空绘制(动物){System.Console.WriteLine(“动物”);}
公共静态void Main(){
var animals=新列表{new Cat(),new Dog()};
foreach(动物中的动态动物){//使用“动态”,而不是“var”
画(动物);//分别画“猫”和“狗”,而不是“动物”
}
}
}
这里的关键是在foreach循环中使用
dynamic
,将每个元素的类型分别从Animal
更改为Cat
和Dog
。有很多方法可以做到这一点。。。作为选项签出-可能使用Piant((动态)动物)
和全套Paint(Cat)
。。。重写。我不明白“两个对象的代码相同”是什么意思,你能展示你的绘画功能吗?@AlexeiLevenkov!有用的指针,谢谢。@user12341234“相同的代码”表示“相同的函数”,即没有动态调度。@user12341234我不确定您的问题是什么。如果您的绘制方法接受类型Animal,那么您的代码将按照您的方式工作。不幸的是,此解决方案似乎迫使我将我的paint
代码与其他代码保持在同一位置。。。猫/狗类中的所有元素。Paint
实际上属于每个特定类。否则,您将需要在“全局”绘制方法中使用一个不断增长的if
或select
语句来满足每种不同的可能动物。一个不断增长的if语句是一种解决方案,尽管它会强制模块紧密耦合。在其他语言中,动态分派或参数多态性是可行的替代方案。我想知道在C#中是否有另一种不需要巨大开关的方法。我不知道为什么在Cat
类中使用所有Cat
代码等等会是一个问题。你能详细介绍一下吗?你见过一只会画画的猫吗?猫知道如何睡觉和发出咕噜声,但我认为,画猫真的应该是画家的工作。