2011-07-26 5 views
2

はのは、私がBaseClassの名前の基本クラスを持っているとしましょう:2つの異なるクラスを同じリストに入れたほうがよいでしょうか?

public BaseClase{ 
    public bool isCool; 
} 

さてさて、私はのインスタンスを含むリストを作成したいとしましょうのは、私がBaseClassの

public Class1: BaseClass{ 
    public bool isGreen; 
} 

public Class2: BaseClass{ 
    public bool isPurple; 
} 

から継承する2つのクラスを持っているとしましょうリストを作成してClass1とClass2の両方を作成します。

var genericList = new List<BaseClass>(); 

次に、Class1とClass2のインスタンスをgenericListに追加しましょう。

genericList.Add(new Class1()); 
genericList.Add(new Class2()); 

ここで私は質問があります。 Class1.IsGreenまたはClass2.IsPurpleにアクセスするには、generic1の各項目をClass1またはClass2としてキャストする必要があります。

foreach(var item in genericList){ 
    if(item is Class1){ 
     var temp = (Class1) item; 
     temp.IsGreen = true; 
    } 
    if(item is Class2){ 
     var temp = (Class2) item; 
     item.IsPurple = true; 
    } 
} 

これはちょうどあなたがやるべきことですか?私にとっては非常に厄介なように思えます。このタイプのコード構造を使用している私が書いているコードの複雑さは、手を抜いています。私は相続が初めてで、これがあなたがやるべきことであるかどうか、あるいはより良い選択肢があるかどうかを学びたいと思っています。

+5

この正確なクラス階層の例を反復処理する方法を説明しない限り、最適な選択を行ったかどうかを特定するために、特定のドメインについて具体的に説明する必要があります。 – Marc

+1

各クラス(ポリモーフィズム)で異なる実装を持つメソッドが必要なようです。次に、リスト内のすべての項目に対して同じメソッドを呼び出すことができます。 – phkahler

答えて

2

本当に何をしようとしているかによって異なります。 IsSelectedのようなプロパティを抽象化することができれば、仮想または抽象的なプロパティとしてBaseClassに公開することができます。そうすれば、for-loopにアイテムをキャストする必要はありません。

また、UpdateColor(bool)のような抽象/仮想メソッドに抽象化することもできます。その後、それぞれの派生クラスはそれをオーバーライドして、適切なプロパティを自分自身に設定できます。

インターフェイスと拡張メソッドなど、いくつかの選択肢がありますが、これを使用してクリーナーを使用することができます。

1

基本的には良い選択肢はあなただけで操作したい場合は、Class1年代を言うものの、その後はOfType拡張子

var genericList = new List<BaseClass>(); 
genericList.Add(new Class1()); 
genericList.Add(new Class2()); 

foreach(var item in genericList.OfType<Class1>()) 
{ 
    // no need to cast 
    item.IsGreen = true; 
} 
+0

これはかなりうれしく、難しい実装は必要ありません – sooprise

0

私はこのようなsomethign言うと、pseudoecodeを使用することができ、ありません!

public sbstract BaseClase{ 
    public bool isCool; 
    public abstract setColor(); 
} 

public Class1: BaseClass{ 
    public bool isGreen; 

    public override void SetColor() {IsGreen=true;} 
} 

public Class2: BaseClass{ 
    public bool isPurple; 
    public override void SetColor() {IsPurple =true;} 
} 

foreach(var item in genericList){ 
    item.SetColor(); 
} 

動作するはずです。..

よろしく。

1

サイクル内で何をしているのかなど、あなたが何とかしているのであれば、アイテムのデフォルトカラーを適用しているので、メソッドIEntity.SetDefaultColors(IColorInformation)を公開し、各アイテムクラスに実装します。

ところでInterface segregation principleと考えて、IEntityのようなエンティティの共通のインターフェイスを導入してください。

0

私はIsGreenをIsSpecialに変更し、IsPurpleをMaximumHappinessに変更します.2つのプロパティが非常に異なる2つのプロパティを表すことがわかりました。

これを処理する方法の1つは、(該当する場合)それらを両方ともベースクラスのプロパティにすることです。したがって、型キャストする必要はありません。

もう1つは、継承クラスがオーバーライドできる基本クラスに関数を提供することです。例えば、関数は "DoSpecialThing"と呼ばれ、その内部では子クラスの任意のプロパティにアクセスできます。

プロパティがブール値であることが保証されている場合(および関連するアイデアの一部を表す場合)、フラグを使用できる可能性があります。例:

[Flags] 
enum MoodType 
{ 
    //Moods 
    Happy, 
    Sad, 
    Elated, 
    Overjoyed, 
    Depressed, 

    //Mental States 
    Confused, 
    Alert, 
    Sluggish, 

    //Other 
    Sleepy, 
    Awake 
} 

ここで、基本クラスには「状態」などと呼ばれるプロパティがあり、それに上記のフラグを組み合わせることができます。だから、あなたは、オブジェクトがスリーピー、混乱、そしてハッピーであることを一つのプロパティで示すことができます。

フラグについて詳しく読むことができます(あなたの状況に該当するかどうかを判断できます)at this link

this SO questionもお勧めします。具体的には、一番上に投票された(受け入れられないものの)回答です。

関連する問題