2011-09-17 84 views
0

PlayerBase是FieldPlayer和GoalKeeper的基類。我在FieldPlayer和GoalKeeper中有stateMachine memeber。但是在MyList中,FieldPlayer和GoalKeeper都被視爲PlayerBase。我如何確保獲得正確類型的stateMachine?我應該不知何故檢查類型,然後typecast?根據對象類型訪問正確的成員

foreach (PlayerBase p in MyList) 
{ 
// Here I need to access p.stateMachine for FieldPlayer or GoalKeeper, depends what p is. 
} 

感謝

+1

is stateMachine不是PlayerBase的成員? – TheCodeKing

+0

使用多態時檢查實際的類型是一種代碼異味。你爲什麼要區分? – BrokenGlass

+0

nope,不能這樣做,它是我爲FieldPlayer和GoalKeepeer – pokoko222

回答

0
foreach (PlayerBase p in MyList) 
{ 
    var fp = p as FieldPlayer; 
    if (fp != null) 
    { 
     // p is a FieldPlayer => you can access the stateMachine property 
     Console.WriteLine(fp.stateMchine); 
    } 
} 
+0

是的,這是我需要的,謝謝 – pokoko222

2

成員應在PlayerBase作爲屬性聲明。也許這是一個抽象聲明,或者至少是一個虛擬聲明。如果屬性需要默認行爲以外的其他屬性,則可以在派生類中重寫該屬性。

abstract class PlayerBase 
{ 
    public abstract TheType StateMachine { get; set; } // declare here 

    // if PlayerBase is not abstract, you can declare the property as: 
    // public virtual TheType StateMachine { get; set; } 
} 

class FieldPlayer : PlayerBase 
{ 
    public override TheType StateMachine { get; set; } // implement here 
} 

通常不想在做類型檢查的代碼與基本類型交易的位置。更多指定(或派生)類型應該能夠直接替換基礎,而不需要代碼關懷。

+0

這就是問題所在,它是一個特定的實現,對於GoalKeeper來說stateMachine與FieldPlayer的不同很多。 – pokoko222

+0

我不同意這一點。爲什麼將'PlayerBase'耦合到'StateMachine'? – Jon

+0

@pokoko,這就是爲什麼你想讓它成爲虛擬的(或抽象的,如果基礎是抽象的)成員,所以孩子們可以用他們自己的實現來覆蓋默認行爲。但是消費代碼(處理'List '的方法不需要關心。 –