假设您有一个名为Food的类,并且您有派生类Banana,Apple和Orange。你有一个FoodProcessor方法,大多数情况下,它可以处理任何类型的食物,但偶尔需要知道它正在处理什么类型的食物,以便做特定类型的事情,比如剥离香蕉,核心苹果,或挤橙。C#标记派生类实例的最好方法
所以你的FoodProcessor需要Food参数。 FoodProcessor检测Food实例的特定派生类型的最佳方法是什么?
假设您有一个名为Food的类,并且您有派生类Banana,Apple和Orange。你有一个FoodProcessor方法,大多数情况下,它可以处理任何类型的食物,但偶尔需要知道它正在处理什么类型的食物,以便做特定类型的事情,比如剥离香蕉,核心苹果,或挤橙。C#标记派生类实例的最好方法
所以你的FoodProcessor需要Food参数。 FoodProcessor检测Food实例的特定派生类型的最佳方法是什么?
当测试对象的类型,我喜欢用is
关键字,像这样:
if(myFood is Bannana)
Peel((Bannana)myFood);
我更喜欢is
因为它也会检查对象是否实现了一个接口。
说到接口,如果您有某些执行特定操作的类型,您可能需要考虑使用接口。检查对特定类型的需要,可以使用不同类型的知识,但是,如果你核对的接口,新的类型可以出现实现此接口,而你需要改变你的代码来处理它们:
if(myFood is IPeelable)
Peel((IPeelable)myFood)
else if(myFood is ICoreable)
Core((ICoreable)myFood)
如果你寻找特定的类型,你现在需要知道每种可能的类型,并且在将来,这是不可扩展的。
这当然假定你不想使用直多态,就像其他答案所描述的一样。
void FoodProcessor(Food food)
{
if(food is Banana)
...
else if(food is Apple)
...
...
etc
}
编辑:如果在其他的答案中提到,您可以使用多态,则忽略此
你应该使用多态性,每个Food
子类将定义一个方法process()
和FoodProcessor
类将简单地调用该方法。
FoodProcessor
public void process(Food f) {
f.process();
}
苹果
public void process() {
Console.WriteLine("Core the apple.");
}
香蕉
public void process() {
Console.WriteLine("Peel the banana.");
}
橙色
public void process() {
Console.WriteLine("Squeeze the orange.");
}
通过这种方式,您可以充分利用Food及其子类之间的继承关系。
我想使它成为抽象的,在每种食品实现它:
abstract class Food {
public abstract void Prepare();
}
class Banana : Food {
public override void Prepare() {
Peel();
}
}
class Apple : Food {
public override void Prepare() {
Core();
}
}
然后你会:
class FoodProcessor {
public void Process(Food food) {
food.Prepare(); // preparation of the food
food.Process();
}
}
我不喜欢多态性答案,因为你基本上是在告诉食物去处理它自己。 (在某些情况下,这会很好,但不是我在这个问题中寻找的东西。)它看起来像“is”关键字是我正在寻找的答案。谢谢大家。 – 2013-02-13 22:09:06
@EdwardNedHarvey这只是一个例子。在我上面的例子中,您可以简单地调用“准备”,然后继续处理食物处理器的“过程”方法中的食物。 – 2013-02-13 22:57:11
@EdwardNedHarvey更重要的是,我觉得这样的设计在SRP的方向发展,其中食品并不比一个数据结构更与OP将增加一类为每个责任,如准备,处理,后处理等。这相当于丢弃封装,这比SRP规则更重要。更不用说使用'is'运算符进行特定类型处理的紧密耦合性和缺乏可伸缩性,这些运算符可以干净地封装在派生类型中。 FWIW – 2013-02-13 23:15:31