假設您有一個名爲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