Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#标记派生类实例的最佳方法_C#_Inheritance - Fatal编程技术网

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

C#标记派生类实例的最佳方法,c#,inheritance,C#,Inheritance,假设您有一个名为Food的类,还有一个名为Banana、Apple和Orange的派生类。你在某处有一种食品加工方法,在大多数情况下,它可以加工任何类型的食品,但偶尔需要知道它在加工什么类型的食品,以便进行特定类型的操作,例如剥香蕉皮、削苹果核或挤压橙子 所以你的食物处理器会处理食物争论。您的食品处理器检测食品实例特定衍生类型的最佳方法是什么 void FoodProcessor(Food food) { if(food is Banana) ... else i

假设您有一个名为Food的类,还有一个名为Banana、Apple和Orange的派生类。你在某处有一种食品加工方法,在大多数情况下,它可以加工任何类型的食品,但偶尔需要知道它在加工什么类型的食品,以便进行特定类型的操作,例如剥香蕉皮、削苹果核或挤压橙子

所以你的食物处理器会处理食物争论。您的食品处理器检测食品实例特定衍生类型的最佳方法是什么

void FoodProcessor(Food food)
{
    if(food is Banana)
        ...
    else if(food is Apple)
        ...

    ...
    etc
}

编辑:如果您可以像其他答案中提到的那样使用多态性,那么忽略此

您应该使用多态性,每个
Food
子类将定义一个方法
process()
,而
FoodProcessor
类将简单地调用该方法

食品处理器

public void process(Food f) {
    f.process(); 
}
苹果

香蕉

public void process() {
    Console.WriteLine("Peel the banana.");
}
橙色的

public void process() {
    Console.WriteLine("Squeeze the orange.");
}

通过这种方式,您可以利用食物及其子类之间的遗传关系。

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

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
关键字,如下所示:

if(myFood is Bannana)
  Peel((Bannana)myFood);
我更喜欢,因为它还将检查对象是否实现接口

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

if(myFood is IPeelable)
  Peel((IPeelable)myFood)
else if(myFood is ICoreable)
  Core((ICoreable)myFood)
如果您寻找特定的类型,那么您现在和将来都需要知道每一种可能的类型,这是不可伸缩的


当然,这是假设你不想像其他答案所描述的那样使用直接多态性。

我不喜欢多态性答案,因为你基本上是在告诉食物自己去加工。(在某些情况下,这很好,但不是我在这个问题中所寻找的。)看起来“是”关键字就是我所寻找的答案。“谢谢大家!”爱德华·哈维,这只是一个例子。在我上面的例子中,你可以简单地调用
Prepare
,然后继续在食品处理器的
Process
方法中处理食品。@EdwardNedHarvey更重要的是,我觉得这个设计正朝着SRP的方向发展,在SRP中,食物只不过是一个数据结构,OP将为每个职责添加一个类,如准备、处理、后处理等。。。这相当于放弃封装,这甚至比SRP规则更基本。更不用说在使用
is
操作符进行特定类型的处理时存在紧密耦合和可伸缩性不足的问题,可以将其干净地封装在派生类型本身中。FWIW@SimonWhitehead添加一个编辑来建议一个接口,你就得到了我的upvote=P他没有给出任何理由来建议我们真的需要一个基础抽象类,它有潜在的陷阱,将我们锁定在一个特定的抽象中(以后可能会很糟糕).对不起-我不是说多态性的答案有任何错误或不好-这确实是一个非常好的答案。我只是说我不想让多态性出现在我现在试图解决的问题中,因为食品处理器实际上知道很多食品不知道的上下文。食品不需要知道齿轮、电和其他食品,它们实际上是现实生活问题的一部分,但在这个论坛问题中没有提到。我接受了“是”的答案,因为这是对所问问题的直接回答,而不是建议需要改变问题。
if(myFood is IPeelable)
  Peel((IPeelable)myFood)
else if(myFood is ICoreable)
  Core((ICoreable)myFood)