2

私はC#のポリモーフィズム/継承の状況に頭を悩ませようとしています。

私が今持っているのはこれらのクラスです:

Lease (the base class containing the general data)
PrivateLease (inheriting from the Lease class)
BusinessLease (inheriting from the Lease class)

私が達成したいのはこれです:

Lease lease = new PrivateLease();

これは現時点では機能しますが、PrivateLeaseこれを行うとオブジェクトのプロパティにアクセスできません。Lease少なくとも、最初にオブジェクトをオブジェクトにキャストせずにPrivateLease

オブジェクトを、またはオブジェクトの1つのすべてのデータを保持するLeaseオブジェクトの一般的なオブジェクトにします。次に、データベースに挿入/更新/削除するときに、データを挿入するテーブルを最初に決定するのはどのタイプかを尋ねます。PrivateLeaseBusinessLease

上記はこの問題を解決するための正しいアプローチではないという奇妙な感覚を持っています。誰かがこれについて何かヒントがありますか?:-)私はグーグルで検索し、プログラミングの本を読みました。誰もが基本クラスを持ち、それから他のクラスに継承するというこのアプローチを提案しています。

どんな助け/ヒントも大歓迎です!

前もって感謝します。

編集

最初から少し詳しく説明しておけばよかったのですが、ごめんなさい!

上記のクラスは、ASP.NETソリューションのUIからのデータを保持しているだけで、データアクセス層を介してデータベースに対してCRUD操作を実行します。したがって、基本的に、これらのクラスには、データを保持するための一連のプロパティのみが含まれています。すなわち:

public class Lease
{
    public int Id { get; set; }
    public bool IsActive { get; set; }
    public string TypeOfRental { get; set; }
    public string RentalPeriod { get; set; }
    public DateTime TakeoverDate { get; set; }        
}

public class PrivateLease : Lease
{
    public string Floor { get; set; }
    public string Side { get; set; }
    public int FloorSize { get; set; }
    public int NumberOfRooms { get; set; }
}

等..

実世界に存在するリース変数が異なるため、クラスとクラスは異なり ますPrivateLease:-)BusinessLease

基本的には、2つの別々PrivateLeaseのオブジェクトを使用することもできますBusinessLeaseが、モデルはAddressオブジェクトが1つ以上Leaseのを保持できることを示しているため、これはオプションではありません。

私には、ASP.NETフロントエンドとDALの両方で主要なキャスティング地獄を経験するように思えますか?:-/

4

5 に答える 5

4

コンシューマーのレイヤーで決定(ロジックを選択)するのではなく、クラス自体で決定しましょう。

// or you ILease interface if a parent class will not contain any shared logic
abstract class Lease
{
    public abstract void Do();

    // example of shared logic
    protected void Save(Lease l) { }
}

class PrivateLease : Lease
{
    public override void Do() { // private logic here }
}

class BusinessLease : Lease
{
    public override void Do() { // business logic here }
}

使用法:

Lease l = ...
l.Do(); // execute the logic

オブジェクトを作成するためのファクトリを作成することをお勧めします。

static class LeaseFactory<T> where T : Lease, new() // constraint to require default constructor existence
{
    public static Leas Create()
    {
        return new T();
    }
}
于 2012-04-06T11:03:46.797 に答える
3

あなたは基本クラスを持つという基本的なアプローチに正しいです。

あなたがする必要があるのは、基本クラスにすべての共通のプロパティを置くことです。次に、異なるビジネスルールがある場合、それらは多態的に呼び出される仮想関数を使用して実装できます。

abstract class Lease
{
  public int MonthlyCost {get;set;}

  public string CustomerName {get;set;}

  // Declare that all Leases have to have an IncreaseCost method.
  public abstract void IncreaseCost();
}

class PrivateLease : Lease
{
  // Private leases are incremented by an absolute number (10).
  public override void IncreaseCost()
  {
    MonthlyCost += 10;
  }
}

class BusinessLease : Lease
{
  // Business leases are incremented by 10%.
  public override void IncreaseCost()
  {
    MonthlyCost *= 1.10;
  }
}

// Somewhere in your code...
Lease lease = new PrivateLease();

// This call is polymorphic. It will use the actual type of the lease object.
lease.IncreaseCost();
于 2012-04-06T10:58:35.870 に答える
1

interfaces現代のOODでは、この状況に使用できます。

編集:

私の意見では、キャストを避けるために、複数の目的のために複数のインターフェースを持つことができます。その後PrivateLeaseBusinessLease適切なものを実装できます。

interface IWrite
{
    string Data { get; set; }
    void Write();
}

interface IRead
{
    string Data { get; set; }
    void Read();
}

public class Lease
{
    //..
}

public class PrivateLease : Lease, IWrite, IRead
{
    // other implementations
    public string Data { get; set; }
    public void Read()
    {
        //..
    }
    public void Write()
    {
        //..
    }
}
public class BusinessLease : Lease, IRead
{
    // other implementations
    public string Data { get; set; }
    public void Read()
    {
        //..
    }
}
于 2012-04-06T11:03:34.640 に答える
0

Leaseクラスで、DBUpdateという仮想メソッドを追加し、両方の派生クラスでオーバーライドします。

一部のユーティリティクラスのLeaseDBOperationメソッドが次のようになっているとします。

public static void LeaseDBOperation (Lease anylease)
{

  anyleaase.DBUpdate();
}

このメソッドは次のように呼び出すことができます。

var pl = new PrivateLease();
..set all the properties of **pl**
//call this for db operations  :
Utility.LeaseDBOperation(pl)

ここLeaseDBOperationメソッドでは、send型に基づく場合、必要なクラスのDBUpdateメソッドが呼び出されます。

于 2012-04-06T16:19:57.443 に答える
-1
Lease l = (Lease)sth;

if (l is PrivateLease)
{
    PrivateLease p = (PrivateLease)l;    
    //do private logic here
}
else if (l if BussinessLease)
{    
    BussinessLease b = (BunessinessLease)l;
    //do bussiness logic here
}
于 2012-04-06T10:59:59.780 に答える