2011-12-26 9 views
2

C#流れるようなインターフェイスキューまたはリスト

public interface IBehaviour 
{ 
    event EventHandler Completed; 
    void Execute(); 
} 

public interface IBehaviourA : IBehaviour 
{ 
    // Some specific stuff here 
    object A { get; set; } 
} 

public interface IBehaviourB : IBehaviour 
{ 
    // Some specific stuff here 
    object B {get;set;} 
} 

public interface IBehaviourQueue 
{ 
    void Run(); 
    BehaviourQueueItem<IBehaviour> AddBehaviour<T>() where T : IBehaviour; 
} 

public class BehaviourQueue : Queue<BehaviourQueueItem<IBehaviour>>, IBehaviourQueue 
{ 
    private IBehaviourFactory factory; 

    public BehaviourQueue(IBehaviourFactory factory) 
    { 
     this.factory = factory; 
    } 

    public BehaviourQueueItem<IBehaviour> AddBehaviour<T>() where T:IBehaviour 
    { 
     T behaviour = factory.GetNew<T>(); 
     var queueItem = new BehaviourQueueItem<IBehaviour>(behaviour); 
     Enqueue(queueItem); 
     return queueItem; 
    } 

    public void Run() 
    { 
     //Run each queue item 
    } 

} 

public class BehaviourQueueItem<T> 
{ 
    public IBehaviour behaviour; 
    public BehaviourQueueItem(IBehaviour behaviour) 
    { 
     this.behaviour = behaviour; 
    } 
    public void WhenComplete(Func<T, bool> action) 
    { 
     CompletedAction = action; 
    } 

    public BehaviourQueueItem<T> ConfigureFor<Z>(Action<Z> dow) where Z : IBehaviour 
    { 
     dow((Z)behaviour); 
     return this; 
    } 
} 

ここでは、私が書くことができるものである。

 var q =new BehaviourQueue(new BehaviourFactory()); 
     q 
      .AddBehaviour<IBehaviourA>() 
      .ConfigureFor<IBehaviourA>(x => x.A = "someValueA") 
      .WhenComplete(x => DoStuffWithSomeProperty(((IBehaviourA)x).A)); 
     q 
      .AddBehaviour<IBehaviourB >() 
      .ConfigureFor<IBehaviourB >(x => x.B = "someValueB") 
      .WhenComplete(x => DoStuffWithSomeProperty(((IBehaviourB)x).B)); 

私が本当に好きではないが、私はどのを指定しなければならないことですIBehaviourのタイプ私はいつも言及しています。 私は書くことができるようにしたいと思います:

 var q =new BehaviourQueue(new BehaviourFactory()); // Queue here is of IBehaviour 
     q 
      .AddBehaviour<IBehaviourA>() 
      .Configure(x => x.A = "someValueA") 
      .WhenComplete(x => DoStuffWithSomeProperty(x.A)); 
     q 
      .AddBehaviour<IBehaviourB>() 
      .Configure(x => x.B = "someValueB") 
      .WhenComplete(x => DoStuffWithSomeProperty(x.B)); 

あなたは私がベース型指定されたリストを作成して、特定の項目を追加し、流暢にそれを設定することができるように書くべきか任意のアイデアを持っていますか?

Edit1:混乱を避けるためにいくつかのコードを削除しました。私の最終的な目標は、上記のコードを書くことです。

感謝

+1

に基づいて念のためにあなたが満足のいく答えを得ることはありません、あなたがこれを掲示する検討する必要がありますコメント

public BehaviourQueueItem<T> ConfigureFor(Action<IBehaviour> dow) { dow(behaviour); return this; } 

EDIT2に基づきます[StackExchangeコードレビューサイト](http://codereview.stackexchange.com)にあります。 – Adam

答えて

2

変更これをして、自分のクラスタイプは、特定の作りが

public interface IBehaviourQueue<T> where T : IBehaviour 
{ 
    void Run(); 
    BehaviourQueueItem<T> AddBehaviour<T>() where T 
} 

からそれを取るタイプを制約して、ちょうどあなたの方法からタイプを削除します。

public class BehaviourQueue<T> : Queue<BehaviourQueueItem<T>>, IBehaviourQueue<T> where T : IBehaviour 
{ 
    private IBehaviourFactory factory; 

    public BehaviourQueue(IBehaviourFactory factory) 
    { 
     this.factory = factory; 
    } 

    public BehaviourQueueItem<T> AddBehaviour() 
    { 
     T behaviour = factory.GetNew<T>(); 
     var queueItem = new BehaviourQueueItem<T>(behaviour); 
     Enqueue(queueItem); 
     return queueItem; 
    } 

    public void Run() 
    { 
     //Run each queue item 
    } 

} 

EDIT1:より多くのコメント

public class BehaviourQueueItem<T> 
{ 
    public T behaviour; 
    public BehaviourQueueItem(T behaviour) 
    { 
     this.behaviour = behaviour; 
    } 
    public void WhenComplete(Func<T, bool> action) 
    { 
     CompletedAction = action; 
    } 

    public BehaviourQueueItem<T> ConfigureFor(Action<T> dow) 
    { 
     dow(behaviour); 
     return this; 
    } 

    public Func<T, bool> CompletedAction { get; set; } 
} 
+0

AddBehaviour から型を削除したため、追加する動作を選択できるようにする必要がありますが、解決策ができません。あなたのコードはqueue.AddBehaviour ()を書くことができません。私が望むだけ多くの異なるタイプの振る舞いを追加できるので、キューは型固有のものであってはなりません。 – JeanT

+0

これらの行動はすべてIBehaviourを実装していますか?もしそうなら、私はコードに問題は見当たりません。ちょうどTをIBehaviourに置き換えてください。 –

+0

コードでは、IBehaviourBまたはIBehaviourAにキューを完全に入力する必要があります。 IBehaviourAまたはIBehaviourBを追加し、ConfigureForメソッドとWhenCompleteメソッドで型を指定する必要がないように、キューはIBehaviourでなければなりません。 – JeanT

関連する問題