C# 事件处理程序为空

C# 事件处理程序为空,c#,events,C#,Events,我目前正在玩LeapSDK。我想创建一个自定义类来封装LeapSDK,这样我就可以简单地将它导入我将来制作的任何应用程序中 LeapSDK为开发人员提供了一个接口,用于向控制器添加侦听器。我们可以定义在监听器中做什么 事实上,我的问题与LeapSDK无关,但我想告诉您我在做什么,以便您了解我的需求。因为我不确定我的工作方法是否好,你可能会有一些建议,比如用聪明的方式做同样的事情。请随意分享 下面是一个示例,描述了它的工作原理(SDK提供的示例): 我已经测试了上面的代码,它工作得很好 现在让我们

我目前正在玩LeapSDK。我想创建一个自定义类来封装LeapSDK,这样我就可以简单地将它导入我将来制作的任何应用程序中

LeapSDK为开发人员提供了一个接口,用于向控制器添加侦听器。我们可以定义在监听器中做什么

事实上,我的问题与LeapSDK无关,但我想告诉您我在做什么,以便您了解我的需求。因为我不确定我的工作方法是否好,你可能会有一些建议,比如用聪明的方式做同样的事情。请随意分享

下面是一个示例,描述了它的工作原理(SDK提供的示例):

我已经测试了上面的代码,它工作得很好

现在让我们来谈谈我的问题。我创建了一个名为LeapEventInterprelator的类,它有一个事件监听器,用于对设备生成的事件进行反应,就像上面的方法一样。我尝试将事件处理程序传递给侦听器,以便侦听器可以调用它来向主应用程序线程生成事件

这是我的密码:

    class LeapEventInterpretator
{
    private Controller controller;
    private DeviceEventListener deviceEventListener;

    public delegate void LeapEventHandler(object sender, Gesture args);
    public event LeapEventHandler GestureDetected;

    public LeapEventInterpretator()
    {
        Connect();    
    }
    private void Connect()
    {
        controller = new Controller();

        deviceEventListener = new DeviceEventListener(GestureDetected);
        controller.AddListener(deviceEventListener);

    }

    public enum Gesture { SwipeLeft, SwipeRight };
}

class DeviceEventListener : Listener
{
    LeapEventInterpretator.LeapEventHandler handler;
    public DeviceEventListener(LeapEventInterpretator.LeapEventHandler h)
    {
        this.handler = h;
    }
    public override void OnConnect(Controller arg0)
    {
        if (this.handler != null)
            handler(this, LeapEventInterpretator.Gesture.SwipeLeft);
    }
}
引发OnConnect时,this.handler为null,因此我无法向应用程序类触发自定义事件。有什么想法吗

同样,这可能是解决问题的愚蠢方法。即使对我自己来说,我也不喜欢将事件处理程序传递给另一个类,但我就是想不出其他方法来完成这项工作。所以请随意评论


非常感谢您的帮助。

在这种情况下,您不希望将事件作为参数传递给侦听器。您希望将回调传递给将引发事件的方法(即委托)

在示例中,行
deviceEventListener=new deviceEventListener(GestureDetected)正在向侦听器传递未初始化的委托(为null)。这是因为您没有将事件作为参数传递,而只是传递事件自动生成的支持字段的值。事件只不过是一对方法(add和remove),外部代码可以使用它们来表示“subscribe me”或“unsubscribe me”

您想做更多类似的事情:

class LeapEventInterpretator
{
    private Controller controller;
    private DeviceEventListener deviceEventListener;

    public delegate void LeapEventHandler(object sender, Gesture args);
    public event LeapEventHandler GestureDetected;

    public LeapEventInterpretator()
    {
        Connect();    
    }
    private void Connect()
    {
        controller = new Controller();

        // pass a callback that will raise the event.
        deviceEventListener = new DeviceEventListener(RaiseGestureDetected);
        controller.AddListener(deviceEventListener);

    }

    // a method to raise the event
    private void RaiseGestureDetected(Gesture gesture)
    {
         var handler = GestureDetected;
         if (handler != null)
             handler(this, gesture);
    }

    public enum Gesture { SwipeLeft, SwipeRight };
}

class DeviceEventListener : Listener
{
    Action<LeapEventInterpretator.Gesture> handler;
    public DeviceEventListener(Action<LeapEventInterpretator.Gesture> h)
    {
        this.handler = h;
    }
    public override void OnConnect(Controller arg0)
    {
        if (this.handler != null)
            handler(LeapEventInterpretator.Gesture.SwipeLeft);
    }
}

谢谢你的帮助。这很有帮助。然而,我发现var handler=GestureDetected;在回调方法中,两者都为null。有什么想法吗?p、 不要担心OnConnect方法,内容只是为了我的测试。@Tingfunc如果
handler
为空,则不会为事件注册任何内容。看我的编辑。哦,我没有改变任何东西,但不知怎么的,它现在工作了。非常感谢,迈克。是的,我把这件事搞砸了。也许我的断点有点超时,我猜是事件触发了。。。谢谢again@tingfungc如果
h
为空,您可以将空检查移动到
DeviceEventListener
构造函数并抛出。然后可以安全地从连接上删除空检查。您应该知道Console.WriteLine是线程安全的,因此“SafeWriteLine”并没有真正为您做任何事情。
class LeapEventInterpretator
{
    private Controller controller;
    private DeviceEventListener deviceEventListener;

    public delegate void LeapEventHandler(object sender, Gesture args);
    public event LeapEventHandler GestureDetected;

    public LeapEventInterpretator()
    {
        Connect();    
    }
    private void Connect()
    {
        controller = new Controller();

        // pass a callback that will raise the event.
        deviceEventListener = new DeviceEventListener(RaiseGestureDetected);
        controller.AddListener(deviceEventListener);

    }

    // a method to raise the event
    private void RaiseGestureDetected(Gesture gesture)
    {
         var handler = GestureDetected;
         if (handler != null)
             handler(this, gesture);
    }

    public enum Gesture { SwipeLeft, SwipeRight };
}

class DeviceEventListener : Listener
{
    Action<LeapEventInterpretator.Gesture> handler;
    public DeviceEventListener(Action<LeapEventInterpretator.Gesture> h)
    {
        this.handler = h;
    }
    public override void OnConnect(Controller arg0)
    {
        if (this.handler != null)
            handler(LeapEventInterpretator.Gesture.SwipeLeft);
    }
}
var interpreter = new LeapEventInterpretator();
intpreter.GestureDetected += (o, g) => { Console.WriteLine("Gesture detected: {0}", g); };
// do something to make the OnConnected get called.