2011-09-28 21 views
5

CheckBoxListから派生したクラスとDropDownListから派生した2つのクラスがあります。それらのコードはまったく同じです。唯一の違いは、私がチェックボックスリストを表示する必要がある場所と、ドロップダウンリストを表示する場所に最初の場所が必要なことです。以下は私のコードされています。今、あなたは内部コードを見ることができるように正確に私は避けたいこれと同じである共通サブクラスを作成して重複コードを削除する方法

using System; 
using System.Collections.ObjectModel; 
using System.Web.UI.WebControls; 

    namespace Sample 
    { 
     public class MyCheckBoxList : CheckBoxList 
     { 
      public int A { get; set; } 
      public int B { get; set; } 
      protected override void OnLoad(EventArgs e) 
      { 
       //dummy task 
       Collection<int> ints = new Collection<int>(); 
       //........ 
       this.DataSource = ints; 
       this.DataBind(); 
      } 
     } 
    } 

秒1

using System; 
using System.Collections.ObjectModel; 
using System.Web.UI.WebControls; 

namespace Sample 
{ 
    public class MyDropDownList : DropDownList 
    { 
     public int A { get; set; } 
     public int B { get; set; } 
     protected override void OnLoad(EventArgs e) 
     { 
      //dummy task 
      Collection<int> ints = new Collection<int>(); 
      //........ 
      this.DataSource = ints; 
      this.DataBind(); 
     } 
    } 
} 

。コードの重複を排除するために共通のクラスを作成するにはどうすればよいですか?

+3

+1は、コードの冗長性を減らすためのものです。あなたの質問はここでよりうまくいくかもしれません:http://codereview.stackexchange.com/ –

+0

@KileyNaro:codereviewについて知っていて、それが存在するかどうかは分かりませんでした。あまりにもそれのための悪い一致のどちらかとは思わないでください。良い質問だと思います。 +1 –

答えて

3

C#の実装の多重継承をサポートしていません(とすでにサブクラス化されているので、あなたは、

public class Entity 
{ 
    public int A { get; set; } 
    public int B { get; set; } 
    Collection<int> GetCollection() 
    { 
     //dummy task 
     Collection<int> ints = new Collection<int>(); 
     //........ 
     return ints; 
    } 
} 

第三のクラスを作成し、あなたができない他のクラスに

public class MyDropDownList : DropDownList 
{ 
    public MyDropDownList() { Entity = new Entity(); } 

    public Entity {get;set;} 
    protected override void OnLoad(EventArgs e) 
    { 
     this.DataSource = Entity.GetCollection(); 
     this.DataBind(); 
    } 
} 
+0

しかし、これは、Entity.AとEntity.Bのような私のプロパティを取得します。私はそれを避けたい。私は自分のaspxページから直接プロパティをしたい。 –

+0

@Rocky:エンティティをカプセル化し、非公開にしてクラスにアクセスするためのプロパティを作成します。 – Arjang

+0

+1はコンポジションを使用していますが、残っているのはEncapsulationを使用してエンティティを内部で作成していたため、外部では必要ありません – Arjang

0

を使用することができます)。コードの一部を3番目のクラスにリファクタリングし、各クラスにインスタンスを持ち、呼び出しを委譲することができます。

このようなものを試すことができます:http://www.codeproject.com/KB/architecture/smip.aspx、それは多くの仕事のように見えます。

+0

私は好奇心があって実際にはわからないからです。 OPは探していますか? –

+1

私はちょうど3番目のオブジェクトに呼び出しを委任するつもりだった。私はC#の代理人に言及していませんでした。 –

+0

清算していただきありがとうございます。何が言いたいのか理解した! –

0

あなたは構図を使用します。これらの2つのクラスに関連しない別のクラスを作成し、その中に共通のコードを持ちます。どちらのクラスでもコードを使用する必要がある場合は、インタフェース。継承を使う必要はありません。

更新:コードの下に(すでにmeziantouによって提供されたコードを修正)

internal interface IEntity 
    { 
     int A { get; set; } 
     int B { get; set; } 
     Collection<int> GetCollection { get; } 
    } 

    internal class Entity : TrialBalanceHTMLToDataTable.TrialBalance.IEntity 
    { 
     public int A { get; set; } 
     public int B { get; set; } 
     public Collection<int> GetCollection 
     { 
      get{ 
      //dummy task 
      Collection<int> ints = new Collection<int>(); 
      //........ 
      return ints; 
      } 
     } 
    } 


    public class MyDropDownList : DropDownList 
    { 
     public MyDropDownList() { _Entity = new Entity(); } 

     private IEntity _Entity { get; set; } 
     protected override void OnLoad(EventArgs e) 
     { 
      this.DataSource = _Entity.GetCollection; 
      this.DataBind(); 
     } 
    } 
+1

-1は、インターフェイスが問題を解決すると言います。定義は引き続きインターフェースを実装する2つのクラス間で複製されます。しかし、共通のコードを別のクラスに移動することを提案するために+1を取得するので、あなたも壊れます! –

+0

@KileyNaro:LOL :)、インターフェースは問題を解決しないので、それらを統一することができます! – Arjang

+0

@KileyNaro:NO!共通のクラスはインターフェイスを実装します。他の2つのクラスは、それを実装するクラスとの会話にのみ使用します。アイデアは2つの異なるクラスのインターフェイスを意味するものではありません。 – Arjang

0

はプロパティを継承することができ、何を達成しようとしていることMyDropDownListある単一のクラスを、持っているように思わDropDownListMyCheckBoxクラスにはCheckBoxクラスのプロパティが継承されますが、2つのMy *クラスにはいくつかの追加プロパティがあります。

他の人も示唆しているように、これを達成する最も簡単な方法はMultiple Inheritanceです。あなたの例で具体的には、それはMyDropDownListMyCheckBoxの間の共有属性を記述する(おそらくabstract)クラスを作成し、それらの2つのクラスをそれぞれのSystem.Web.UI.WebControlsベースとこの "共有"クラスの両方から継承させることを意味します"クラス。しかし、そのリンクを経由して、クリスBrummeからC# doesn't support multiple inheritance.、それは言われているよう:

MIが本当に適切な場所の数は、実際には非常に小さいです。多くの場合、複数のインタフェースの継承が、代わりにジョブを完了させることができます。他のケースでは、カプセル化と委任を使用することができます。

また、Interfacesの使用を検討したことがあります。 というインタフェースでは、クラス内に特定のプロパティとメソッドがあるが、プロパティやメソッドがどのように定義されているかを定義することはできません。再度、これは重複したコードを削除するための不適切な選択です。

これはどういう意味ですか?さて、もしmyCustomDDLInstance.SelectedIndexmyCustomDDLInstance.Aの両方の構文をサポートしているMyDropDownListクラスを書くには、ちょっとした "魔法"をする必要があります。 あなたの言語があなたがしようとしていることをサポートしていないという事実は、赤い旗を掲げるべきです!必ずしも間違っているわけではありませんが、あなたのデザインを再検討したいという強いインジケータになるはずです。

私の推測では、2つのクラスの複製された部分は、それが独自の論理エンティティのように独立できることです。これは、これらの共有プロパティとメソッドを保持する独自のクラスを正当に作成できることを意味します。ここでは、何を得るのです。

SampleControl.cs

public class SampleControl 
{ 
    public int A { get; set; } 
    public int B { get; set; } 

    public Collection<int> MysteryCollection 
    { 
     get 
     { 
      Collection<int> ints = new Collection<int>(); 
      //........ 
      return ints; 
     } 
    } 
} 

CSHARPは、イン実際のサポート多重継承しなかった場合は、お使いのMyDropDownListクラスがDropDownListSampleControlの両方から継承することができ、あなたが行われることと思います。しかし再び、これは不可能です。

私たちはどのように目標を達成していますか?ちょっと複雑ですが、各カスタムクラスの共有プロパティとメソッドをEncapsulateにすることができます。ここでMyDropDownListクラスの例です(単にクラス名を変更し、MyCheckBoxListが同じになることに注意してください:

public class MyDropDownList : DropDownList 
{ 
    private SampleControl mySampleControl { get; set; } 

    public int A 
    { 
     get 
     { 
      return mySampleControl.A; 
     } 

     set 
     { 
      mySampleControl.A = value; 
     } 
    } 

    public int B 
    { 
     get 
     { 
      return mySampleControl.B; 
     } 

     set 
     { 
      mySampleControl.B = value; 
     } 
    } 

    public MyDropDownList() 
    { 
     mySampleControl = new SampleControl(); 
    } 

    protected override void OnLoad(EventArgs e) 
    { 
     //dummy task 
     this.DataSource = mySampleControl.MysteryCollection; 
     this.DataBind(); 
    } 
} 

このように設計されたクラス、少し複雑ながら、あなたが探しているタイプの構文を達成する必要があります。

のために最後の注意として、私は強く少なくともに再検討し、あなたのデザイン、あなたのクラス階層をアプローチするためのより良い方法があるかどうか見て検討してください。私の推薦があれば、あなたの共有属性ということであることをお勧めします論理エンティティとして単独で存在することができますが、それらはおそらく独自のクラスである必要があります。もしそうであれば、そのクラスはprobabですあなたのMyDropDownListMyCheckBoxクラスの正当で論理的なメンバーです。つまり、で、myDropDownListInstance.SharedAttributesClassName.Aの構文を使用する必要があります。それはもっと明白でより正直です。

+0

これは作曲、http://en.wikipedia.org/wiki/Composition_over_inheritance – Arjang

関連する問題