ほとんどの人が知っているように、WCF は "オブジェクト指向" という意味での継承をサポートしていません。そうは言っても、回避策はありますが、オーバーヘッドがかかります。これらの回避策には、KnownTypes と ServiceKnownTypes が含まれます。ネットワーク全体のメッセージング プロセスを簡素化し、パフォーマンスを維持するために、「データ転送オブジェクト」の使用を検討しています。これらのオブジェクトを「エンティティ クラス ライブラリ」と、2 つの別個の CLR 継承構造に従うテスト ライブラリでテストしました。以下は、それぞれを簡単に表したものです。
最初のケース:
このケースでは、Book クラスが継承するのと同じ IBook インターフェイスから BookDTO が継承されます。Book から BookDTO への「直接」継承はありません。
2 番目のケース:
この 2 番目のケースでは、BookDTO が Book および IBook から直接継承できます。これは、必要に応じて直接キャストを介して Book と BookDTO 間の疎結合と互換性を可能にするオブジェクト指向コードをサポートするため、最も柔軟な構造のようです。さらに、Book には、IBook インターフェイスと同様に、論理的な親があります。ただし、明らかな問題は、暗黙的に含まれるインターフェイス メンバーのプロパティに WCF DataMemberAttribute 属性を実装すると、親クラスのプロパティが非表示になるため、Visual Studio で警告がスローされることです。
私の質問:「データ転送オブジェクト」を介して簡素化されたメッセージング インフラストラクチャをサポートしながら、クラス ライブラリで適切な継承を許可することが私の意図である場合、親プロパティを取得および設定するプロパティのローカル バージョンを作成することをお勧めしますか? 以下のコード参照を参照してください。
[DataContract(Name="BookDTO")]
class BookDTO: Book, IBook
{
[DataMember(Name="Author")]
string Author { get { return base.Author; } set { base.Author = value; } }
[DataMember(Name = "Publisher")]
string Publisher { get { return base.Author; } set { base.Author = value; } }
[DataMember(Name = "Id")]
int Id { get { return base.Id; } set { base.Id = value; } }
[DataMember(Name = "Name")]
string Name { get { return base.Name; } set { base.Name = value; } }
}
これにより、コンパイラ警告 CS0108 (レベル 2 警告) がスローされることは事実です。「new」キーワードを使用することで、これを克服できます。私の質問は、オブジェクト指向コードの論理的な継承を考えると、上記の 2 つが推奨される場合の構造であるということですか? シリアル化のためにクラス階層をフラット化する機能には利点がありますが、DataContractAttribute と DataMemberAttribute を各プロパティに追加する必要があります。
私がこれを行っている理由は、「Book」および「BookDTO」の実際の製品コードで配列シリアル化を実行するいくつかのカスタム型があるためです。さらに、複数の種類の製品を期待していますが、「製品」クラスは抽象のままであり、それ自体で実装することはできません。
ケース 2 で直感的に正しいかどうか、または BookDTO が IBook インターフェイスからのみ派生するケース 1 で「警告のない」構造を考慮する必要があるかどうかを教えてください。
追記: BookDTO から Book ... (Book)BookDTO へのアップキャストをサポートしているため、ケース 2 の構造が気に入っています。次のようなキャスト構造をサポートする場合よりも、ASP.NET の OOP モデルでのアップキャストははるかに安価 (ほぼ無料) です。オブジェクト間でソートカットとキャストを行うことにしました。さらに、キャストにはルート インターフェイスに戻る必要があります。これだけでちょっと萎えます…