2012-08-24 55 views
5

我有2種類型:BaseQuestionQuestionQuestion繼承BaseQuestion的一些屬性。現在我已經創建了一個Web API來使BaseQuestion可用。數據類型Question具有我不想提供的其他屬性。我有一種方法檢索Question,我的初始計劃是將其隱式地上傳到BaseQuestion。我認爲它會失去所有我不想訪問的額外屬性,我可以將其退回。 嗯,它不。這是我做的:C#:超類在upcast後仍然有子類信息

Question q = allQuestions[0]; 
BaseQuestion bq = q; 
string type = bq.GetType().ToString(); 

bq的類型仍然是「問題」。我無法訪問BaseQuestion屬性,但我仍然可以在調試器中看到它們,並且它們位於發送給客戶端的JSON輸出中。

關於如何「強制」bq的類型爲BaseQuestion並且沒有在子類中定義的任何屬性的任何想法?

+0

變量類型BQ的是BaseQuestion。 bq引用的對象的運行時類型是問題。不知道你的意思是「強制bq是BaseQuestion類型」。您只能通過變量bq訪問BaseQuestion成員。 – lesscode

+1

我認爲你的困惑並不瞭解你給出的內容是**引用**到內存中的對象。 –

+0

西蒙,好點。然後讓我改述:如何創建一個類型爲Question的新對象並自動複製所有屬性值?自動地我的意思是我做**不**想實現它。恕我直言,這種情況是不是獨一無二的我的情況,應該由.NET覆蓋。 – Jan

回答

11

類型轉換不會改變對象的性質,它只會改變對象的視圖。當你對基類型進行類型轉換時,通過一個只能看到在基類型上定義的成員的過濾器來查看對象,而不管在實際對象中定義了什麼。

當您從Web服務調用中返回一個對象時,它將是序列化的實際對象,並通過線路發回 - 它的所有可序列化成員。

您可以使用一種技術來阻止將派生Question類的成員返回給API調用方,即禁止在Question類中聲明的成員的序列化。在.NET中有幾個序列化子系統,但如果您使用XmlSerialization,則會用[XmlIgnore]屬性修飾Question類中聲明的成員,以防止它們被XmlSerialization序列化。如果您使用的是不同的序列化子系統,則需要在該系統中找出這種類比。

另一種可能性是爲您的Web API服務定義接口契約。您的BaseQuestion和Question類將實現一個或多個這些合同接口。我相信這會將序列化限制爲僅限於契約接口中定義的屬性,而不管實際對象是什麼。

如果一切都失敗了,暴力解決方案是在臨時變量中構造一個BaseQuestion實例,將實際Question對象的相關屬性複製到該臨時對象,並返回該臨時對象。這是粗魯和粗暴的,這應該是一種更好的方式,但它會起作用。

+0

我無法更改Question/BaseQuestion類型,因爲Web API不是它們的唯一用戶。我完全同意「有一個更好的方法」,我一直在尋找,但是空空如也。我認爲我的沮喪感足以創造一個明確的轉換器。但感謝您的幫助! – Jan

+0

除了基於接口繼承限制序列化的部分外,這個答案的大部分都是正確的。該部分不起作用,因爲它不會更改原始對象。我希望它的工作方式如下: –

+0

而不是創建一個「契約接口」,創建任何你想要序列化和反序列化的「契約模型」。編寫轉換函數或使用像[AutoMapper]這樣的庫(https:// github.com/AutoMapper/AutoMapper)將你的「完整」模型轉換爲只包含你想要序列化的屬性的精簡版本 – MarioDS

1

類型轉換隻改變對象的引用類型,而不是對象本身。

Question的實例上調用.GetType()將始終返回Question類型,而不管引用它的變量類型如何。

如果你想要基類型,那麼你需要調用.BaseType屬性的類型。

所以,這樣的事情:

string type = q.GetType().BaseType.ToString(); 
+0

這只是爲了展示我的意思,我需要一個包含_only_包含的對象基類的屬性 – Jan

+0

這不是什麼類型轉換爲'BaseQuestion'會給你嗎? – Enigmativity

+0

這就是我的想法,但顯然它不是。我不改變對象本身,我只更改容器我存儲這個子類的屬性仍然存在,並且會被序列化 – Jan