C#标记派生类实例的最佳方式

本文关键字:最佳 方式 实例 派生 | 更新日期: 2023-09-27 17:59:07

假设您有一个名为Food的类,并且您有名为Banana、Apple和Orange的派生类。你在某个地方有一个FoodProcessor方法,它在很大程度上可以处理任何类型的食物,但偶尔需要知道它在处理什么类型的食物才能做一些特定类型的事情,比如香蕉去皮、苹果去核或挤橘子。

所以你的FoodProcessor接受了Food的论点。FoodProcessor检测Food实例的特定派生类型的最佳方法是什么?

C#标记派生类实例的最佳方式

您应该使用多态性,每个Food子类将定义一个方法process(),而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及其子类之间的继承关系。

在测试对象类型时,我喜欢使用is关键字,如下所示:

if(myFood is Bannana)
  Peel((Bannana)myFood);

我更喜欢is,因为它还会检查对象是否实现了接口。

说到接口,如果您有执行特定操作的特定类型,您可能需要考虑使用接口。针对特定类型进行检查需要了解可能使用的不同类型,但是,如果您针对接口进行检查,则可以出现实现该接口的新类型,而无需更改代码来处理它们:

if(myFood is IPeelable)
  Peel((IPeelable)myFood)
else if(myFood is ICoreable)
  Core((ICoreable)myFood)

如果你寻找特定的类型,你现在和将来都需要知道每一种可能的类型,这不是很容易扩展的。

当然,这是假设您不想使用直接多态性,正如另一个答案所描述的那样。

我会将其抽象化,并在每种食物中实现:

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();
    }
}
void FoodProcessor(Food food)
{
    if(food is Banana)
        ...
    else if(food is Apple)
        ...
    ...
    etc
}

edit:如果你可以使用其他答案中提到的多态性,那么忽略这个