根据订阅者的要求通知订阅者的 C# 事件

C# Event to Notify Subscribers Based on Their Requirement

我有一个 class 形状可以改变颜色,它应该在发生变化时通知订阅者。但是,订阅者希望收到如下通知:

这是我的形状class

public class Shape  
{  
    public event EventHandler ColorChanged;  

    void ChangeColor()  
    {  
        // set new color 

        OnColorChanged(...);  

    }  

    protected virtual void OnColorChanged(MyEventArgs e)  
    {  
        if(ColorChanged != null)  
        {  
           ColorChanged(this, e);  
        }  
    }  
} 

还有我的订阅者

public class Subscriber1
{
    public Subscriber1(Shape shape)
    {
        shape.ColorChanged += new EventHandler(OnColorChanged);
    }

    void OnColorChanged(object sender, EventArgs e)
    {
        // this subscriber wants to get notified only if color changes to green, yellow and red
    }
}

public class Subscriber2
{
    public Subscriber2(Shape shape)
    {
        shape.ColorChanged += new EventHandler(OnColorChanged);
    }

    void OnColorChanged(object sender, EventArgs e)
    {
        // this subscriber wants to get notified only if color changes to red
    }
}

public class Subscriber3
{
    public Subscriber3(Shape shape)
    {
        shape.ColorChanged += new EventHandler(OnColorChanged);
    }

    void OnColorChanged(object sender, EventArgs e)
    {
        // this subscriber wants to get notified every time shape color changes
    }
}

我如何让 Shape 通知这些订阅者他们喜欢的颜色变化(即我只想在你的颜色变成红色时收到通知)?

我看到的每个示例都会将所有更改通知所有订阅者,我正在努力做到这一点

您必须为每个不同的可能订阅选择维护一个委托列表:

private Dictionary<Color, EventHandler> colorChangedHandlers;

private EventHandler color_changed_to_red;
private EventHandler color_changed_to_yellow;
.
.
.
// then, add all of the delegates to the list

订阅者必须致电

shapeInstance.SubscribeColorChanged(EventHandler handler, params Color[] desiredColors);

然后,您必须实施它,如下所示:

public void SubscribeColorChanged(EventHandler handler, params Color[] colors)
{
  foreach (Color c in colors)
  {
    colorChangedHandlers[c] += handler;
  }
}

当然,您还需要配套的 Unsubscribe 方法:

public void UnsubscribeColorChanged(EventHandler handler, params Color[] desiredColors)
{
  foreach (Color c in desiredColors)
  {
    foreach (KeyValuePair<Color, EventHandler> kvp in colorChangedHandlers)
    {
      if (kvp.Key == c) {
        EventHandler tmp = kvp.Value;
        tmp -= handler;
      }
    }
  }
}

然后,您将不得不更改 OnColorChanged 方法

protected virtual void OnColorChanged(Color color)
{
  colorChangedEventHandlers[color]?.Invoke(this, EventArgs.Empty);
}

所有这些都只是针对一个 ColorChanged 事件,可以用 NewColor 属性 在 EventArgs 的派生 class 上处理! !另外,对于自定义颜色,它必须更复杂,因为这只处理 Colors 枚举中的值。 这可能是可行的,但我不会向任何没有明确和迫切需要它的人推荐它。