0

Customer エンティティと Order エンティティがあります。流暢な休止状態を使用して顧客のクラスを定義するときに、注文リスト プロパティに「保護されたセット」を指定する必要があるのはなぜですか。

public virtual IList<Order> Orders { get; protected set; }
4

1 に答える 1

2

protectedon setterを指定する必要はありません。そうするのはちょうど良い設計です。

セッターでアクセス修飾子が指定されていない場合、プロパティ自体と同じアクセス修飾子が暗黙的に設定されpublicます(この場合)。setter が public の場合、クラスのコンシューマはOrdersプロパティを変更して別のインスタンスに設定できます。

public class Customer
{
    public virtual IList<Order> Orders { get; set; }
}

var customer = new Customer();
customer.Orders = new List<Order>();

setter でアクセス修飾子を定義するprotectedと、継承されたクラスのみがプロパティを変更できます。他のコンシューマには、Ordersプロパティは読み取り専用として表示されます。これは実質的にカプセル化です。

NHibernate はデフォルトで遅延読み込みを使用します。これは、一部のプロパティ (通常はリスト) がすぐに読み込まれるのではなく、最初の使用時に読み込まれる手法です。NHibernate はこれをプロキシで実装します。動的に作成されるプロキシ クラスは、Entityクラスから継承し、そのすべてのプロパティをオーバーライドします。virtualそれが、すべてのクラス メンバーにある理由です。

要するに、定義するprotected setと、NHibernate の動的プロキシがプロパティを変更できるようになりOrdersます。Orders空のプロキシ コレクションに初期化される可能性があり、誰かがそれを読み込もうとすると、データベースのロードがトリガーされ、Ordersプロパティがデータベースからロードされた Order インスタンスのリストに置き換えられます。

public class Customer
{
    public virtual IList<Order> Orders { get; protected set; }
}

var customer = new Customer();
//customer.Orders = new List<Order>(); // error: can't modify property

var orderCount = customer.Orders.Count; // this will trigger lazy-loading
于 2012-09-11T22:11:33.857 に答える