创建自定义事件 - 对象发件人或键入发件人? [英] Creating custom events - Object Sender or Typed Sender?

查看:136
本文介绍了创建自定义事件 - 对象发件人或键入发件人?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我搜索过的档案,我发现很多的问题,什么是发件人,以及为何要使用该模式,但我没有看到一个自定义的事件和键入的,如果发件人。什么

I searched through the archives and I found lots of questions about what sender is and why you should use the pattern but I didn't see anything about a custom event and the type if sender.

说我是创建一个名为自定义类认购,并实现了ISubscription和我有一些事件参数称为SubscriptionEventArgs。如果订阅了所谓的事件改变了什么是错的关于事件的签名改成(ISubscription发件人,SubscriptionEventArgs E)?

Say I am creating a custom class called Subscription and it implements ISubscription and I have some event args called SubscriptionEventArgs. If Subscription had an event called Changed what is wrong about the event signature Changed(ISubscription sender, SubscriptionEventArgs e)?

一个小code,有助于推动问题:

A little code to help drive the question:

public class SubscriptionEventArgs : EventArgs
{
    // guts of event args go here
}

public interface ISubscription
{
    event Action<ISubscription, SubscriptionEventArgs> Changed;
}

public class Subscription : ISubscription
{
    public event Action<ISubscription, SubscriptionEventArgs> Changed;

    private void OnChanged(SubscriptionEventArgs e)
    {
        if (Changed!= null)
        {
            Changed(this, e);
        }
    }
}

如果你只是鄙视用行动到位事件处理程序,那么你可以做同样的事情,但有一个自定义的通用事件处理程序。

If you just despise the use of action in place of "EventHandler" then you could do the same thing but with a custom generic "EventHandler".

public delegate void EventHandler<TSender, TEventArgs>(TSender sender, TEventArgs e);

public class SubscriptionEventArgs : EventArgs
{
    // guts of event args go here
}

public interface ISubscription
{
    event EventHandler<ISubscription, SubscriptionEventArgs> Changed;
}

public class Subscription : ISubscription
{
    public event EventHandler<ISubscription, SubscriptionEventArgs> Changed;

    private void OnChanged(SubscriptionEventArgs e)
    {
        if (Changed!= null)
        {
            Changed(this, e);
        }
    }
}

在回应汉斯的要求提供样本事件处理程序:

In response to Hans' request for a sample event handler:

public class SubscriptionCollection
{
    // what is actually holding the subscriptions is not really relevant to the question
    private List<ISubscription> _subscriptions;

    public SubscriptionCollection()
    {
        _subscriptions = new List<ISubscription>();
    }

    public void Add(ISubscription subscription)
    {
        subscription.Changed += new EventHandler<ISubscription, SubscriptionEventArgs>(Subscription_Changed);
        _subscriptions.Add(subscription);
    }

    private void Subscription_Changed(ISubscription sender, SubscriptionEventArgs e)
    {
        // Now when the subscription changed event is being handled by the collection
        // I don't have to look up the subscription in the list by some key and I don't 
        // have to cast sender to the correct type because the event handler was typed
        // correctly from the beginning.
    }
}

在列表中订阅的查询可能看起来微不足道,但如果我有非常大的数据集和数据的新卷的工作内容是通过实时数据流,在未来的应用程序。不必停下来,找一个引用了一个列表或者通过铸造的步骤没有任何意义的成本。他们给了我们仿制药在2.0解决这个问题,所以我不明白为什么我们没有一个通用的事件处理程序也是一样,这让我怀疑有什么问题一般事件处理程序?

The lookup of the subscription in the list might seem trivial but what if I am working with very large sets of data and new volumes of data are coming at the application through a real-time stream. The cost of having to stop and get a reference out of a list or go through the steps of casting don't make sense. They gave us generics in 2.0 to solve that issue so I don't understand why we didn't get a generic event handler too and this led me to question what is wrong with a generic event handler?

推荐答案

其实,我感到很困惑,为什么,设计.Net框架V2时,微软并没有提供一个事件处理程序你刚才描述的方式 - 以 TSender TEventArgs 既是通用的参数。 (在v1和1.1版,因为他们没有仿制药,我完全理解他们为什么没有让成千上万的额外委托类型来处理所有可能的事件。)如果我记得正确的,你仍然可以使用一个通用处理器听一个更具体的事件:

I actually am quite confused why, when designing the .Net Framework v2, MS didn't provide an EventHandler just the way you described - with the TSender and TEventArgs as both generic arguments. (In v1 and v1.1, since they didn't have generics, I completely understand why they didn't make thousands of extra delegate types to handle all the possible events.) If I remember properly, you can still use a generalized handler to listen to a more specific event:

public event EventHandler<Button, MouseDownEventArgs> MouseDown;

private void ObservingMethod(object sender, EventArgs e) { }

MouseDown += new EventHandler<Button, MouseDownEventArgs>(ObservingMethod);

既然你不暴露观察者可观察到的,我看不出这可能是一个问题;你只是preventing需要做类型检查以防万一,一旦你到事件处理程序。我觉得这是一个梦幻般的做法,虽然自MS有点不标准决定不将其列入。

Since you're not exposing the observer to the observable, I don't see how this could be a problem; you're just preventing the need to do type-checking 'just in case' once you get to the event handler. I think it'd be a fantastic practice, although a bit non-standard since MS decided not to include it.

正如我在评论上面提到的,我想preFER看到事件处理程序的如下定义,让您真正总是可以使用一个非常广义的处理方法,因为我的code样品:<​​/ P>

As noted in my comment above, I would prefer to see the following definition of EventHandler, so that you really could always use a very generalized handler method, as my code sample:

public delegate void EventHandler<TSender, TEventArgs>(TSender sender, TEventArgs e)
    where TEventArgs : EventArgs;

这篇关于创建自定义事件 - 对象发件人或键入发件人?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆