2

特定のサブクラスごとに固有のオブジェクトをカプセル化するスーパークラスを持つコードを書いています。たとえば、以下は、サブクラスのタイプとそれがカプセル化するクラスのタイプの関係の例です。カプセル化するすべてのクラスには、カプセル化するクラスへの暗黙のキャストもあります。(抽象的でないもの)。

Item => Model.Item
Box => Model.Box

タイプ セーフでないタイプを使用するよりも、objectジェネリックを使用してタイプ セーフとエレガンスを得ることができると感じました。

public abstract class Entity<T> where T: class
{
    protected T DataObject;
}

public class Item : Entity<Model.Item>
{
    // Can use this.DataObject and it is type Model.Item
}

public class Box : Entity<Model.Box>
{
    // Can use this.DataObject and it is type Model.Box
}

このアプローチは、第 2 レベルのサブクラスの作成を開始するまで問題なく機能したため、の定義をに変更しました ( extendsItemに注意) 。Model.AItemModel.Item

public class Item<T> : Entity<T> where T : Model.Item
{
    // Can use this.DataObject and it is type Model.Item
}

public class AItem : Item<Model.AItem>
{
    // Can use this.DataObject and it is type Model.AItem
}

これには 2 つの主な問題があります。1 つは、第 2 レベルのオブジェクトを、入れなければならない抽象クラスとして参照しItem<Model.Item>たい場合です。真実。また、インスタンス化できないため、抽象クラスを使用した暗黙のキャストに大混乱をもたらします。

何も機能しません。基本的には、具体的に型指定されたカプセル化されたオブジェクトを持つ機能を維持しながら、遺伝パラメーターを削除したいと考えています。カプセル化されたオブジェクトは、実際には Linq to SQL オブジェクトであり、周囲のオブジェクトは、他の機能を実装すると共に、変更のための一種のバッファーを形成し、アプリケーション内のデータをより直接的に表現します。LinqToSql エンティティを保持する必要があるため、車輪を再発明することなく、LinqToSql を使用して変更を更新し、挿入/削除を管理する方法があります。これを行うために部分クラスを使用していましたが、異なるデータコンテキストに属するオブジェクトとの混同が多すぎました。

編集:全話

さまざまな種類の調査オブジェクトで構成される調査評価があります。実際の質問オブジェクトなどの一部の調査オブジェクトは、さまざまな他のオブジェクトで構成されています。たとえば、ブロックは itembank を持つ調査オブジェクトであり、item bank はさまざまなタイプ (現在はサブクラスとして表されている) のアイテムで構成されています。これまでのところ、Linq to SQL エンティティをモデルとして直接使用し、部分クラスを介していくつかの変更を加えてきました。アイテムには、調査でアイテムが呼び出される前後に実行されるスクリプトがあります。このスクリプトはアイテムの特定のプロパティを変更できますが、linq の性質上、変更を加えた場合は常に linq クラスがモデルであるため、これらの変更をデータベースに保持する必要があります。

物事を行うためのより良い方法を見ている人はいますか?

4

1 に答える 1

2

共分散と反分散についてはこちらをご覧ください。を作成しinterface IEntity<out T> where T : class { T DataObject { get; } }、抽象クラスにこれを実装させることができる場合があります。その後、この種の変換を暗黙的に行うことができます。

IEntity<Model.AItem> a = //something
IEntity<Model.Item> b = a; //it works!

共変インターフェースを使用してこれを行うことができない場合は、しようとしていることを実際に論理的に行うことはできず、別の角度から解決策を見つけようとする必要があります。

于 2012-08-06T19:35:39.330 に答える