2012-03-16 12 views
1

ここにはOOの問題があります。私は共通のプロパティと特定のプロパティを持つ2つのセッションを持っています。私は基本クラスを作成し、すべての共通プロパティ/メソッドをカプセル化しました。 2つのセッションには、Rangesという共通のタイプがあります。これには、セッションに共通のプロパティと固有のプロパティがあります。したがって、私はこの場合にスーパータイプにプログラムし、実行時にインスタンスを構築できると考えました。Cでのスーパータイプへのプログラミング#

public class Level 
{ 
    private readonly Ranges _range; 

    public Level(Ranges range) 
    { 
     _range = range; 
    } 

    public Ranges Range 
    { 
     get { return _range; } 
    } 

    public void CommonMethod() 
    { 
     throw new NotImplementedException(); 
    } 

    public int CommonProperty; 
} 

public class ALevel : Level 
{ 
    public ALevel() 
     : base(new ARange()) 
    { 

    } 

    public int ALevelProperty; 
} 

public class BLevel : Level 
{ 
    public BLevel() 
     : base(new BRange()) 
    { 

    } 

    public int BLevelProperty; 
} 

public class Ranges 
{ 
    public int CommonRangeProperty; 
} 

public class ARange : Ranges 
{ 
    public int ARangeProperty; 

    public ARange() 
    { 

    } 
} 

public class BRange : Ranges 
{ 
    public int BRangeProperty; 
} 

public class ASession 
{ 
    public ASession() 
    { 
     Level = new ALevel(); 
    } 

    public ALevel Level { get; set; } 
} 

public class BSession 
{ 
    public BSession() 
    { 
     Level = new BLevel(); 
    } 

    public BLevel Level { get; set; } 
} 

私がセッションオブジェクトを作成するとき、それは特定の範囲のASessionのRangesプロパティを含んでいません。 基本クラスのプロパティにのみアクセスできます aSession.Level.Range.CommonRangeProperty = 1; aSessionの特定のプロパティ aSession.Level.Range.ARangePropertyにアクセスできません。

ここで何か問題がありますか?

public class Test 
{ 
    public static void Main(string[] args) 
    { 
     ASession aSession = new ASession(); 

     aSession.Level.Range.CommonRangeProperty = 1; 
     //Not able to see ARangeProperty 

    } 
} 

答えて

3

それはかなり簡単です:RangesからRangeの種類(ない特定のARangeBRange)を設定しますLevel

クラス。

public abstract class Level<TRange> 
    where TRange : Ranges 
{ 
    private readonly TRange _range; 
    protected Level(TRange range) 
    { 
     this._range = range; 
    } 
    public TRange Range 
    { 
     get 
     { 
      return this._range; 
     } 
    } 
} 

public class ALevel : Level<ARange> 
{ 
    public ALevel() 
     : base (new ARange()) 
    { 
    } 
} 

あなたはさらに、この例を取ることができます: あなたは例えば、ジェネリックで動作するはず

public abstract class Level<TRange> 
    where TRange : Ranges/*, new()*/ // i'm not sure about the new() ... have no compiler access right now to check! 
{ 
    private readonly TRange _range = new TRange(); 
    public TRange Range 
    { 
     get 
     { 
      return this._range; 
     } 
    } 
} 

public class ALevel : Level<ARange> 
{ 
} 

私たちのあなたがそうのように、ALevel内の別のメンバーを紹介することができます:

public class ALevel : Level 
{ 
    public ARange ARange; 
} 

この例を改善するには、RangeLevelに仮想化して上書きするRange(redirec tをコンクリートのレベルARangeまたはBRange)に変更します。それは大きく、その後の使用に依存

... あなたがRangesとしてproprety Rangeへの一般的なアクセスを必要とする場合は、あなたのジェネリックで上書きすることができ、ベース部材を、導入する(一般的な制約なし)、別の基本クラスを導入すべきですベースクラス。だから、私が正しくあなたの問題を理解していれば...

+0

うわー! Urソリューションはシンプルで強力でした。ありがとうございました!しかし、コードの問題を私に説明できますか? – sundar

+0

@sundar私の最初の文章では、あなたのクラスレベルが範囲の範囲を(特定のARangeでもBRangeでもなく)設定していることを説明しようとしました。 –

+0

ですが、Rangesはスーパータイプなので、派生型を割り当てることができます。 – sundar

1

あなたがジェネリックを使用する必要があります(基本クラスO /あなたが具体的なTRangeの知識がLevel<TRange>にキャストする必要がありますw)はLevelALevelのインスタンスをキャストすることができますあなたが達成しようとしていることをする。あなたのコードは

public class Level<TRange> 
    where TRange: Ranges 
{ 
    private readonly TRange _range; 

    public TRange Range 
    { 
     get 
     { 
      return this._range; 
     } 
    } 
} 

public class ALevel : Level<ARange> 
{ 

} 

のようになります。そのスーパークラスはRangeを基本型として使用でき、派生クラスはそれを特定の型として使用できるようになります。

+0

'プライベート'の可視性のために 'ALevel'は' Level._range 'にアクセスできません。 '_range'をprotectedとしてマークするか、または' protected' get-プロパティを導入するべきです –

+0

@AndreasNiedermair良いキャッチ...固定 – Yaur

+0

あなたは大歓迎です! –

関連する問題