2012-08-24 11 views
5

私は2種類あります:BaseQuestionQuestionです。 Questionは、BaseQuestionからいくつかのプロパティを継承します。今私はBaseQuestionを利用できるようにするWeb APIを作成しました。 Questionデータ型には、追加できないプロパティがあります。 Questionを取得するメソッドがあり、私の初期の計画は暗黙的にそれをBaseQuestionにアップキャストすることでした。私はそれが私がアクセス可能にしたくない、それを返すことができるすべての追加プロパティを失うと思った。 まあ、そうではありません。これは私が行うことです:C#:スーパークラスはアップキャスト後にサブクラス情報を持っています

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

bqのタイプはまだ "質問"です。私はBaseQuestionのプロパティにアクセスすることはできませんが、私はまだデバッガでそれらを見ることができ、クライアントに送るJSON出力にあります。

私はどのようにしてbqをタイプBaseQuestionにすることができ、サブクラスで定義されているプロパティは持たないかについてのアイデアはありますか?

+0

変数BQのタイプはBaseQuestionです。 bqが参照するオブジェクトの実行時の型はQuestionです。 "bqがBaseQuestion型であることを強制する"という意味がわからない変数bqを介してのみBaseQuestionメンバーにアクセスすることができます。 – lesscode

+1

私はあなたの混乱は、あなたが与えたことがメモリ内のオブジェクトへの参照**であることを理解していないと思います。 –

+0

サイモン、良い点。それでは、質問をタイプして新しいオブジェクトを作成し、すべてのプロパティ値を自動的にコピーするにはどうすればいいですか?自動的に私はそれを実装したくない**ことを意味します。 IMHOこのシナリオは私の状況に固有のものではなく、.NETでカバーする必要があります。 – Jan

答えて

11

Typecastingはオブジェクトの性質を変更するものではなく、オブジェクトの表示のみを変更します。基本型に型キャストすると、実際のオブジェクトで定義されているものに関係なく、基本型で定義されたメンバしか見ることのできないフィルタを介してオブジェクトが参照されます。

Webサービスコールからオブジェクトを返すと、そのオブジェクトはシリアル化され、ワイヤを介して返される実際のオブジェクトです。そのすべてのシリアライズ可能なメンバーです。

派生したQuestionクラスのメンバーがAPI呼び出し元に返されないようにするために使用できる手法の1つは、Questionクラスで宣言されたメンバーの直列化を抑制することです。 .NETにはいくつかのシリアライゼーションサブシステムがありますが、XmlSerializationを使用している場合、XmlSerializationによってシリアル化されないように、[XmlIgnore]属性を使用してQuestionクラスで宣言されたメンバーをデコレートします。異なるシリアライゼーション・サブシステムを使用している場合、そのシステムでこれと類似したものを把握する必要があります。

もう1つの可能性は、Web APIサービスのインタフェース契約を定義することです。あなたのBaseQuestionとQuestionクラスは、それらの契約インタフェースの1つ以上を実装します。私はこれが実際のオブジェクトが何であるかにかかわらず、シリアル化を契約インタフェースで定義されたプロパティだけに制限すると考えています。

他のすべてが失敗した場合は、一時的なvarにBaseQuestionのインスタンスを作成し、実際のQuestionオブジェクトから関連するプロパティをtempオブジェクトにコピーし、tempオブジェクトを返します。これは無礼で原油であり、よりよい方法が必要ですが、それはうまくいくでしょう。

+0

Web APIが唯一のユーザーではないため、Question/BaseQuestionタイプを変更できません。私は完全に "良い方法があるはずだ"ということに同意し、私はその場所を見渡していたが空になった。私の不満は、明示的なコンバータを作成するのに十分な大きさだと思います。しかし、助けてくれてありがとう! – Jan

+0

インターフェイスの継承に基づくシリアル化を制限する部分を除いて、この回答のほとんどは正しいです。元のオブジェクトは変更されないため、その部分は機能しません。 ( –

+0

)「契約インタフェース」を作成するのではなく、シリアライズおよびデシリアライズしたいものの「契約モデル」を作成します。変換関数を記述するか、[AutoMapper](https:// github.com/AutoMapper/AutoMapper)を使用して、フルモデルを、シリアル化するプロパティのみを含むスリムダウンバージョンに変換します。 – MarioDS

1

型キャストは、オブジェクト自体ではなく、オブジェクトへの参照の型のみを変更します。

.GetType()Questionのインスタンスで呼び出すと、それを参照する変数の型に関係なく、常にQuestionの型が返されます。

基本タイプを使用する場合は、そのタイプの.BaseTypeプロパティを呼び出す必要があります。

ので、このような何か:

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

これは、私が意味することを示すことに過ぎません。ベースクラスのプロパティ – Jan

+0

'BaseQuestion'にどのような型キャストがありますか? – Enigmativity

+0

それは私が思ったものですが、明らかにそうではありません。オブジェクト自体は変更されません。 – Jan

関連する問題