收听继承类的特定事件

时间:2011-11-03 11:08:05

标签: c# events design-patterns .net-2.0

假设我们有以下类结构:

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 个答案:

答案 0 :(得分:1)

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使用不同的方法。

答案 1 :(得分:0)

您需要实现一个处理命令的命令处理程序。让苹果落下是命令的一个例子。

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的启发。

答案 2 :(得分:0)

如果农场有水果,那么它只能订阅水果活动。

在你的基类中定义一个虚拟事件,即Fruit,然后在你的不同Fruits子类中覆盖它,就像苹果那样是FallFromTree。

查看此更多详情 C#: What are virtual events and how can they be used?