2013-02-13 43 views
2

假設您有一個名爲Food的類,並且您有派生類Banana,Apple和Orange。你有一個FoodProcessor方法,大多數情況下,它可以處理任何類型的食物,但偶爾需要知道它正在處理什麼類型的食物,以便做特定類型的事情,比如剝離香蕉,核心蘋果,或擠橙。C#標記派生類實例的最好方法

所以你的FoodProcessor需要Food參數。 FoodProcessor檢測Food實例的特定派生類型的最佳方法是什麼?

回答

1

當測試對象的類型,我喜歡用is關鍵字,像這樣:

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

我更喜歡is因爲它也會檢查對象是否實現了一個接口。

說到接口,如果您有某些執行特定操作的類型,您可能需要考慮使用接口。檢查對特定類型的需要,可以使用不同類型的知識,但是,如果你覈對的接口,新的類型可以出現實現此接口,而你需要改變你的代碼來處理它們:

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

如果你尋找特定的類型,你現在需要知道每種可能的類型,並且在將來,這是不可擴展的。

這當然假定你不想使用直多態,就像其他答案所描述的一樣。

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

    ... 
    etc 
} 

編輯:如果在其他的答案中提到,您可以使用多態,則忽略此

1

你應該使用多態性,每個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及其子類之間的繼承關係。

0

我想使它成爲抽象的,在每種食品實現它:

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(); 
    } 
} 
+0

我不喜歡多態性答案,因爲你基本上是在告訴食物去處理它自己。 (在某些情況下,這會很好,但不是我在這個問題中尋找的東西。)它看起來像「is」關鍵字是我正在尋找的答案。謝謝大家。 – 2013-02-13 22:09:06

+0

@EdwardNedHarvey這只是一個例子。在我上面的例子中,您可以簡單地調用「準備」,然後繼續處理食物處理器的「過程」方法中的食物。 – 2013-02-13 22:57:11

+0

@EdwardNedHarvey更重要的是,我覺得這樣的設計在SRP的方向發展,其中食品並不比一個數據結構更與OP將增加一類爲每個責任,如準備,處理,後處理等。這相當於丟棄封裝,這比SRP規則更重要。更不用說使用'is'運算符進行特定類型處理的緊密耦合性和缺乏可伸縮性,這些運算符可以乾淨地封裝在派生類型中。 FWIW – 2013-02-13 23:15:31