Слушайте конкретные события унаследованных классов - PullRequest
0 голосов
/ 03 ноября 2011

Предположим, у нас есть следующая структура класса:

public class Fruit
{
    public event EventHandler<RipeEventArgs> Ripe;
}

public class Apple:Fruit
{
    public event EventHandler<FallEventArgs> FallFromTree;
}

public class Farm
{
    List<Fruit> fruits;
}

public class Farmer
{
    private Farm myFarm;

    public Farmer()
    {
        // listen to all FallFromTree events coming from the farm
        myFarm.WHAT += AppleFallen;
    }

    public void AppleFallen(object sender, FallEventArgs e) {}
}

Вопрос : Как мне убедиться, что фермер может прослушивать все события FallFromTree с любого яблока на ферме и любого яблока, которое будет создано в будущем?

Я думал об отдельных событиях пузырей, но это означало бы, что Farm должен определять каждое событие, которое также охватывается Apple. Проблема в том, что я буду создавать много разных фруктов с разными событиями, и важно, чтобы какой-то особый фермер мог слушать только определенные события, которые приходят с фермы. Поэтому определение каждого нового типа события в Farm не кажется мне решением.

Ответы [ 3 ]

1 голос
/ 03 ноября 2011

Просто сообщите Farm о Farmer, а не Farmer о Farm.

public class Fruit
{
    public event EventHandler<RipeEventArgs> Ripe;
}

public class Apple:Fruit
{
    public event EventHandler<FallEventArgs> FallFromTree;
}

public class Farm
{
    List<Fruit> fruits;
    Farmer farmer;

    public Farm(Farmer farmer)
    {
        this.farmer = farmer;
    }

    public void AddFruit(Fruit fruit)
    {
        farmer.RegisterForEvents(fruit);
        fruits.Add(fruit);
    }
}

public class Farmer
{
    private Farm myFarm;

    public Farmer()
    {

    }

    public virtual void RegisterForEvents(Fruit fruit)
    {
       //Farmer decides what events it is interested in: can override in derived classes
       if(fruit is Apple)
       {
           ((Apple)fruit).FallFromTree += AppleFallen;
       }
    }

    public void AppleFallen(object sender, FallEventArgs e) {}
}

Предложение fruit is Apple не идеально, но я думаю, что единственное, что вы можете здесь сделать, это реализовать двойную диспетчеризацию или использовать разные методы на Farmer для каждого типа Fruit.

0 голосов
/ 03 ноября 2011

Что ж, если у фермы есть фрукты, то она может подписываться только на события из фруктов.

Определите виртуальное событие в вашем базовом классе, например, Fruit, а затем переопределите его в различных дочерних классах Fruits, как для apple, это будетbe FallFromTree.

Подробнее см. C #: Что такое виртуальные события и как их можно использовать?

0 голосов
/ 03 ноября 2011

Вам необходимо реализовать обработчик команд, который будет обрабатывать команды.Сделать падение яблока является примером команды.

public class MakeAppleFallCommandHandler
{
    public void Execute(Apple apple)
    {
      //This method would be called whenever any apple in the farm falls

      FallFromTree(apple);
    }

    public event EventHandler<FallEventArgs> FallFromTree;
}

Тогда в классе фермеров вы можете подписаться на MakeAppleFallCommandHandler.FallFromTree.Это вдохновлено CQRS.

...