2012-05-31 95 views
2

我正在構建一個多層應用程序。如何從具體類轉換爲接口類型?

當我從表示層傳遞一個對象到我的業務層時,我想將它轉換爲接口類型,因爲業務層不知道表示層的具體類。

public ActionResult SubmitSurvey(SurveyAnswer answers) 
    { 

     ISurveyAnswer answer = (ISurveyAnswer)answers; 

     bc.SaveSurvey(answer); 

     return null; 
    } 

SurveyAnswer實現接口ISurveyAnswer

當我檢查在業務層的類型:

public void SaveSurvey(ISurveyAnswer answer) 
     { 
      String type = answer.GetType().Name; 
     } 

對GetType()名稱方法返回SurveyAnswer這與具體類。表示層。它應該這樣做嗎?

回答

8

鑄造不會更改對象的類型。該對象始終與創建時相同。鑄造只是改變你通過其訪問對象的界面。如果您願意,它會改變對象的「視圖」。不過這不是問題。你在做什麼是正確的。所有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<>。但是,當你決定你的方法的參數類型時,該原則是一個非常好的原則。

您幾乎從不需要知道傳入方法的對象的實際類型。您真正需要知道的是它實現了一個特定的接口,以便您可以通過該特定接口訪問其功能。

+0

當我在業務層接收對象時,對象的正確操作是什麼?我應該將它映射到另一個對象,因爲它來自業務層上的一個層?謝謝 – Kenci

+0

@Kenci我添加了一些例子和進一步的解釋,希望能爲你解決問題。 –

4

我想將它轉換爲一個接口類型

沒有必要。如果具體類型實現該類型,則不需要投射它。

這會工作得很好。

public ActionResult SubmitSurvey(SurveyAnswer answers) 
{ 
    bc.SaveSurvey(answers); 
    return null; 
} 

對GetType()名稱方法返回SurveyAnswer這是從表現層的具體類。它應該這樣做嗎?

這是正確的。它將返回正在傳入的實際類型(無論您將其投入了哪個類型)。

相關問題