鑄造不會更改對象的類型。該對象始終與創建時相同。鑄造只是改變你通過其訪問對象的界面。如果您願意,它會改變對象的「視圖」。不過這不是問題。你在做什麼是正確的。所有UI層關心的是ISurveyAnswer接口,只要對象的具體類型實現了該接口,那麼一切都會很好,並且可以按照您的預期工作。這樣做的好處是,現在UI層可以被賦予任何類型的對象(包括模擬對象),並且無關緊要,只要對象實現了相同的接口,UI將會工作並且不會在意。 GetType可以讓你檢查對象,看看對象的實際類型是什麼,但是在大多數情況下,對UI層來說應該沒有關係。只要提供的對象實現了該接口並且正常工作,UI也將如此。
當任何類或方法要求將某種類型的對象傳遞給它時,理想情況下它應始終要求儘可能最窄的實現或基類型。因此,舉例來說,如果你有需要的項目列表的方法,它可能是這個樣子:
void printList(List<Dog> dogs)
{
foreach(Dog dog in dogs)
printDog(dog);
}
但是,從技術上講,該方法並不真的需要一個List<>
對象,因爲所有它做的是枚舉列表中的項目。它不使用List<>
類型的任何成員,它本身只使用接口的成員,該接口由List<>
類型實現。因此,這將是在這種情況下更好的像這樣的代碼的方法:
void printList(IEnumerable<Dog> dogs)
{
foreach(Dog dog in dogs)
printDog(dog);
}
現在,如果裏面的方法,它不僅需要在列表中列舉,但也需要在項目的總數列表,然後IEnumerable
是不夠的。但儘管如此,它不會需要完整List<>
類型,它只是需要ICollection<>
型(也由List<>
實現),像這樣:
void printList(ICollection<Dog> dogs)
{
printTotal(dogs.Count);
foreach(Dog dog in dogs)
printDog(dog);
}
但是,如果方法neededs獲得每個項目的索引,ICollection<>
是不夠的 - 該方法需要IList<>
類型。例如,這個例子說明它如何打印狗的名單,並強調每隔1個清單:
void printList(IList<Dog> dogs)
{
printTotal(dogs.Count);
for(Dog dog in dogs)
if (dogs.IndexOf(dog) % 2 == 0)
printDog(dog);
else
printHighlightedDog(dog);
}
你會發現,在沒有這些例子,我纔不得不投了dogs
參數成不同類型。我爲我需要的東西適當地輸入了參數,所以我只是通過該類型的接口來使用它。在所有這些例子中,List<Dog>
對象可以被傳遞到printList
方法而無需進行轉換(因爲名單<>實現所有這些接口,因此它可以被隱式轉換):
List<Dog> dogs = new List<Dog>();
dogs.Add(new Dog());
printList(dogs);
請記住,這是一個非常簡單的例子來說明一個觀點。在現實世界的情況下,即使您技術上不需要他們提供的所有東西,但出於各種原因,您經常可能會要求List<>
或IList<>
。您可能知道該方法未來可能需要IList<>
功能,儘管它現在只需要功能IEnumerable<>
。但是,當你決定你的方法的參數類型時,該原則是一個非常好的原則。
您幾乎從不需要知道傳入方法的對象的實際類型。您真正需要知道的是它實現了一個特定的接口,以便您可以通過該特定接口訪問其功能。
當我在業務層接收對象時,對象的正確操作是什麼?我應該將它映射到另一個對象,因爲它來自業務層上的一個層?謝謝 – Kenci
@Kenci我添加了一些例子和進一步的解釋,希望能爲你解決問題。 –