【问题标题】:C# Subscribing to Events Using InterfacesC# 使用接口订阅事件
【发布时间】:2017-05-22 23:40:28
【问题描述】:

我最近开始使用 C# 事件,我真的很喜欢它们提供的易用性(我来自 java 背景,我们必须手动完成所有这些事件)。

但是,在我的 java 背景中,我缺少一件事:继承方面。

在java中,如果你想订阅一个事件,你会继承一个接口,比如IKeyListener。该接口将包含您将在订阅类中实现的所有方法事件签名。每当按下某个键时,就会触发这些已实现的方法。与 C# 大致相同。但是,与 java 不同的是,我无法确定哪些类订阅了某些事件,因为它们实际上并没有继承任何东西。

所以如果我想要一个支持按键事件的对象列表,我可以这样做

List<IKeyListener> keyListeners = new ArrayList<IKeyListener>();

但是,我看不到在 C# 中执行此操作的任何好方法。我将如何创建类似于上述列表的列表?最好不要太多“hackiness”。

谢谢。

【问题讨论】:

  • 虽然您在问题中提到 Java,但问题本身与创建 Java 程序无关,因此 java 问题标签不合适。我已经为你删除了。

标签: c# events interface event-handling


【解决方案1】:

在 C# 中,您可以在如下界面中定义事件:

public interface IDrawingObject  
{  
    event EventHandler ShapeChanged;  
} 

然后你可以做你想做的事情并像这样存储它们:

var shapes = new List<IDrawingObject>();

然后一个类可以像这样实现接口:

public class Shape : IDrawingObject  
{  
    public event EventHandler ShapeChanged;  
    void ChangeShape()  
    {  
        // Do something here before the event…  

        OnShapeChanged(new MyEventArgs(/*arguments*/));  

        // or do something here after the event.   
    }  
    protected virtual void OnShapeChanged(MyEventArgs e)  
    {  
        if(ShapeChanged != null)  
        {  
           ShapeChanged(this, e);  
        }  
    }  
} 

换句话说,事件成为接口的一部分,如果一个类实现了该接口,那么该类也必须为该事件提供一个实现。这样你就可以安全地假设实现类有事件。

最后,每个活动都需要分享一些关于该活动的信息。该类可以继承EventArgs 类,如下所示:

public class MyEventArgs : EventArgs   
{  
    // class members  
}  

【讨论】:

  • 这与我要找的很接近。但是,如果我不希望 Shape 类成为“触发”事件的类怎么办?我想让一个类调用事件,然后让另一个类订阅被调用的事件。所以假设我有一个蓝图类,它需要知道某个形状何时发生变化(并且该形状不是蓝图的成员)。我怎么能做到这一点而不必也是调用事件的类?我也有可能完全错过了一些东西。如果有请告诉我,谢谢:)
  • 但是你为什么要这样做呢?整个想法是让班级拥有这种知识,而没有其他人。如果我有一个带有点击事件的按钮,我只想让按钮说它被点击了。我不希望其他类说它被点击了,因为如果没有点击怎么办。
  • @exonto 如果您希望blueprint 类知道shape 何时更改,那么blueprint 可以订阅shape 类的change 事件。但只有shape 应该触发该事件。触发此事件的所有代码都应在 shape 类中。
  • 现在我仔细想想,这真的归结为这个。我想有一些方法来要求一个类订阅一个事件。我的想法是接口需要实现它们的方法,然后可以以某种方式用于要求它订阅。我想我只是使用了 List 示例,因为这是我以前做过的事情。但我明白你在说什么,我会违背目的。话虽如此,请允许我重新表述我的问题。如何确保某个课程订阅了某个事件?
  • 我的例子中的形状类有这个代码if(ShapeChanged != null) 这基本上意味着如果有人订阅了然后通知他们。这就是你现在要问的吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多