2013-05-06 50 views
6
[DataContract] 
public class SearchCriteria 
{ 
    [DataMember] 
    public string CountryID { get; set; }  
} 

[DataContract] 
public class CitySearchCriteria: SearchCriteria 
{ 
    [DataMember] 
    public string CityID { get; set; } 
} 

我在我的MVC控制器動作創建SearchCriteria實例,並試圖 其轉換成CitySearchCriteria。無法投基類(數據合同)到派生類

SearchCriteria searchCriteria = new SearchCriteria(); 
searchCriteria.CountryID = "1"; 
CitySearchCriteria citySearchCriteria = searchCriteria as CitySearchCriteria; 

上述語句之後的 「citySearchCriteria」 對象被表示NULL值。我期待它顯示兩個屬性,CountryID和CityID與CountryID填充,並且CityID空白...但它將該對象設置爲NULL。

這裏有什麼解決辦法? DataContract對此做了什麼?

的意見所提出的建議,你不能轉換的基礎來推導: 但實際上,我已經在我看來成功地做到了這一點,它只是沒有在控制器操作的工作:

CitySearchCriteria citySearchCriteria = (CitySearchCriteria)Model.SearchCriteria; 

這是成功轉換,那麼爲什麼不能在控制器操作中使用類似的東西?

+0

您不能從基礎派生到派生。反過來可能是 – noobob 2013-05-06 06:05:54

+0

請查看問題的最後兩段 – Nirman 2013-05-06 06:50:00

+0

再次檢查Martin的答案(第一個例子)。 – noobob 2013-05-06 06:51:31

回答

5

每個人都已經(並且正確地)告訴過你,你根本無法從Base轉換爲Derived,但在我看來,你仍然不明白爲什麼這行代碼在另一塊代碼中工作:

CitySearchCriteria citySearchCriteria = (CitySearchCriteria)Model.SearchCriteria; 

我認爲你對某個實例的「類型」有些困惑。你沒有崗位模型的定義,但我認爲你有這樣的事情:

public SearchCriteria SearchCriteria; 

這並不意味着SearchCriteria總是包含SearchCriteria實例,但只有它包含的類型的實例,可以被投射到SearchCriteria。在你的情況下,它可以包含SearchCriteria或CitySearchCriteria的實例。我想,在某個地方你的代碼,你會發現這樣的:

Model.SearchCriteria = new CitySearchCriteria(); 

,這就是允許正確執行侑演員。你可以看到,該實例確實是一個CitySearchCriteria(而不是簡單地SearchCriteria的一個實例)剛剛投之前執行此代碼:

MessageBox.Show(Model.SearchCriteria.GetType().FullName; 

爲了更好地理解你可以嘗試只是你的工作之前修改SearchCriteria值如下所示投射,以發現演員陣容不再有效:

Model.SearchCriteria = new SearchCriteria(); 
MessageBox.Show(Model.SearchCriteria.GetType().FullName; 
CitySearchCriteria citySearchCriteria = (CitySearchCriteria)Model.SearchCriteria; 
+0

謝謝,是的,你是對的,我對此有很多困惑。這些細節已經澄清了同樣的情況,並且我可以看到我在編碼時出錯。謝謝 – Nirman 2013-05-06 12:00:35

6

你不能這樣!

如果你做new你創建一個特定大小的新內存對象。在你的情況下,new SearchCriteria()創建一個具有足夠大小的新內存對象來存放一個字符串,僅此而已,沒有限制。

在您的最後一行中,您嘗試searchCriteria as CitySearchCriteria嘗試將searchCriteria中的對象轉換爲較大的類型CitySearchCriteria。但它不能完成。你正試圖將一個存放1個字符串的內存對象轉換成一個可以容納2個字符串的內存對象。但是,轉換不會轉換新的內存對象。新字符串的價值是什麼?它只是在水下看起來,以檢查您的參考searchCriteria是否已經包含CitySearchCriteria類型的對象。在你的情況:它不(該對象是SearchCriteria類型)並返回null

所以...下一個例子工作(因爲CitySearchCriteria已經創建)。這也是您的解決方案:

SearchCriteria searchCriteria = new CitySearchCriteria(); 
CitySearchCriteria citySearchCriteria = searchCriteria as CitySearchCriteria; 

而且這並不行(因爲CitySearchCriteria尚未創建)。這是你的情況:

SearchCriteria searchCriteria = new SearchCriteria(); 
CitySearchCriteria citySearchCriteria = searchCriteria as CitySearchCriteria; 

這與下一個例子是一樣的。
做工作(因爲SearchCriteria已經創建):

object o = new SearchCriteria(); 
SearchCriteria searchCriteria = o as SearchCriteria; 

,這是否(因爲SearchCriteria尚未創建)::

object o = new object(); 
SearchCriteria searchCriteria = o as SearchCriteria; 

對於記錄:我總是使用直接投射,而不是使用as的投射,除非您想顯式測試一個對象是否屬於這種類型。

+0

它只是不能被轉換,因爲基於他的實現,演員陣營將無法從基礎類派生到派生類。反過來是可能的。 – noobob 2013-05-06 06:09:50

+0

我認爲這正是我所說的......不是嗎?還是我想念你的意思?我的文章中有哪些例子是不正確的? – 2013-05-06 06:13:49

+0

@noobob:哪一個是錯的? – 2013-05-06 06:16:58

2

您可以創建CitySearchCriteria,並將其轉換爲SearchCriteria。這樣你只能看到CountryId。稍後,您可以將其轉換回CitySearchCriteria,並查看CountryId和CityId。

這與DataContract無關。在你的情況下解決方案將創建CitySearchCriteria並將其投射到SearchCriteria(如果你需要它)。

+0

我發現了兩個類似的問題:http://stackoverflow.com/questions/988658/unable-to-cast-from-parent-class-to-child-class 和http://stackoverflow.com/questions/ 9885644/cast-the-parent-object-to-child-object-in-c-sharp – uross 2013-05-06 06:17:13

+0

問題是,我的視圖期待一個「SearchCriteria」對象,因爲它已從多個位置調用,它可以有「CitySearchCriteria」 ,「StateSearchCriteria」等等,這取決於呼叫控制器和操作。另外,我已經成功地在我的視圖內完成了這項工作,例如CitySearchCriteria citySearchCriteria =(CitySearchCriteria)Model.SearchCriteria;而且工作正常,那麼爲什麼不在控制器操作? – Nirman 2013-05-06 06:22:09