2011-12-26 2 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)); 

У вас есть какие-либо идеи, что я должен написать, чтобы иметь возможность создать базовый напечатал список и добавлять определенные элементы и настройки его свободно?

Редактировать 1: Удалено код, чтобы избежать путаницы. Моя конечная цель - написать вышеприведенный код.

Большое спасибо

+1

только в случае, если вы не получили удовлетворительного ответа, вы можете рассмотреть вопрос о регистрации этого на [веб-сайте обзора сайтов 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 BehaviourQueueItem<T> ConfigureFor(Action<IBehaviour> dow) 
{ 
    dow(behaviour); 
    return this; 
} 

edit2: более на основе комментариев

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. Очередь должна быть IBehaviour, поэтому я могу добавить IBehaviourA или IBehaviourB и не указывать тип в методах ConfigureFor и WhenComplete. – JeanT

Смежные вопросы