通用事件处理程序 [英] Generic Event Handlers

查看:93
本文介绍了通用事件处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,
我是.net的初学者,我对此进行了研究,但我没有得到确切的目的
我在网上搜索了一下,但答案并没有消除我的疑问.能否请你消除我的疑问?

谢谢
Prashant P

Hi All,
I am beginner to .net and I studied about it but I am not getting the exact purpose
of them.I searched on net but the answers didnt cleared my doubt .Could you please clear my doubt?

Thanks
Prashant P

推荐答案

我认为通用事件处理程序不存在.您的意思可能是通用类型System.EventHandler:
http://msdn.microsoft.com/en-us/library/system.eventhandler.aspx [ ^ ].

令人困惑的部分是:这是称为EventHandler的通用委托类型,它本身不是事件处理程序,而是特别是定义事件处理程序签名的委托类型.而且事件处理程序始终是method(命名或匿名),用于将其添加到事件实例的调用类型中.除了这种混乱之外,事件实例类型不是其声明中使用的类型.它是某个类的实例.换句话说,声明
I don''t think generic event handlers can exist. What you mean is probably the generic type System.EventHandler:
http://msdn.microsoft.com/en-us/library/system.eventhandler.aspx[^].

The confusing part is: this is the generic delegate type called EventHandler, which is not an event handler itself, but a delegate type which, in particular, defines the signature of an event handler. And the event handler is always a method (named or anonymous) which is used to be added to the invocation type of an event instance. In addition to this confusion, the event instance type is not a type used in its declaration. It''s the instance of some class. In other words, the declarations
int Value; // the type of the object Value is int
//...
internal event EventHandler<MyEventArgs> SomethingHappened; // the type of SomethingHappened is NOT EventHandler<MyEventArgs>


它们的含义有很大的不同:在第一种情况下,对象的类型与对象左侧的声明类型相同;在第二种情况下,事件实例(对象)的实际类型与声明的类型无关.

现在,让我们从头开始,并显示完整的示例.这是事件的声明:


their meaning is dramatically different: in first case, the type of the object is the same as declared type on the left of it; in the second case, the actual type of the event instance (object) and the declared type are unrelated.

Now, let''s start from the very beginning and show the complete sample. Here is the declaration of event:

public class MyEventArgs : System.EventArgs {
    internal MyEventArgs(/* some parameters ... */); // never needs to be public, because an event can be invoked in the declaring class only
    public // some properties specific to 
}

//...

public class MyEventDeclaringClass {
    public event EventHandler<MyEventArgs> SomethingHappened;

    internal InvokeWhenSomethingHappened() {
        if (SomethingHappened != null)
            SomethingHappened.Invoke(this, new MyEventArgs(/* appropriate arguments, will be used in event handler */));
    }
}



通过使用上面的某些public声明,我假设可以在同一程序集中或在某些其他程序集中实现类MyEventDeclaringClass并处理其事件.现在,用法:



By using some public declarations above, I assumed that the class MyEventDeclaringClass and handling its event can be possible in the same assembly or on some other assembly. And now, the usage:

MyEventDeclaringClass myInstance = new MyEventDeclaringClass(/* ... */);
//...

myInstance.SomethingHappened += (sender, eventArgs) => { // adding a handler to the event invocation list
   // use eventArgs properties passed when InvokeWhenSomethingHappened is called, see above
};
// the type of sender is System.Object (according to the code of InvokeWhenSomethingHappened, the run-time type is the instance MyEventDeclaringClass)
// the type of eventArgs is MyEventArgs
// the two types are known to the compiler from the type of myInstance.SomethingHappened via type inference

// the same thing without using the lambda syntax and type inference:
myInstance.SomethingHappened += delegate(System.Object sender, MyEventArgs eventArgs) { /* ... */ }



如您所见,泛型System.EventHandler<>允许抽象出事件参数的实际类型,同时避免非泛型System.EventHandler所需的类型强制转换.换句话说,它用于相同目的,而泛型则用于其他情况.

这不是正式要求,而是使用事件机制的推荐方法.您需要始终使用两个参数,第一个应为object,第二个应为始终从System.EventArgs派生的自定义类型.

另请参见:
http://en.wikipedia.org/wiki/Anonymous_method [ http://msdn.microsoft.com/en-us/library/0yw3tz5k.aspx [ ^ ];

http://en.wikipedia.org/wiki/Type_inference [ http://msdn.microsoft.com/en-us/library/bb308966.aspx# csharp3.0overview_topic10 [ ^ ],
http://msdn.microsoft.com/en-us/vstudio/jj131514.aspx [ ^ ].



顺便说一句,混淆的命名很常见.例如,名称System.Object类的名称,而不是对象.对于那些了解事物本质的人来说,这并不是真正的问题.同样,该语法允许为变量或类型的成员赋予与它的类型相同的名称;甚至建议这样做.您首先需要区分类型,实例(对象),变量,类型的字段,属性(和其他成员),然后考虑它们的作用.



另请参阅我过去对相关问题的回答:
如何在特定按钮单击时调用keydown事件 [ ^ ],
[已解决]如何为C#控件添加事件 [ ^ ],
有关用户控件,嵌套控件和封装的问题. [^ ],
WPF:如何在自定义控件中使用事件 [ ^ ].

而且,有关匿名方法和诸如 closure 之类的重要内容的更多信息:
什么是C#中的匿名类型? [ ^ ],
创建新线程的循环会出现问题 [ ^ ],
http://en.wikipedia.org/wiki/Closure_%28computer_science%29 [ ^ ].

—SA



As you can see, the generic type System.EventHandler<> allows to abstract out the actual type of the event arguments and at the same time avoid type cast which would be needed for non-generic System.EventHandler. In other words, it is used for the same purposes generics are used for in other cases.

This is not required formally, but recommended way of using the mechanism of events. You need to use always two parameters, first should be object, and the second one should be the custom type always derived from System.EventArgs.

See also:
http://en.wikipedia.org/wiki/Anonymous_method[^],
http://msdn.microsoft.com/en-us/library/0yw3tz5k.aspx[^];

http://en.wikipedia.org/wiki/Type_inference[^],
http://msdn.microsoft.com/en-us/library/bb308966.aspx#csharp3.0overview_topic10[^],
http://msdn.microsoft.com/en-us/vstudio/jj131514.aspx[^].



By the way, confusing naming is pretty usual. For example, the name System.Object is the name of the class, not object. For those who understand the essence of things, this is not really a problem. Also, the syntax allows to give a variable or a type''s member the same name as its type; and this is even recommended. You need first to distinguish between types, instances (objects), variable, type''s fields, properties (and other members), and then consider their roles.



Please see also my past answers to related questions:
how to call keydown event on particular button click[^],
[Solved] How to add Event for C# Control[^],
A question about usercontrols, nested controls and encapsulation.[^],
WPF : How to Use Event in Custom Control[^].

And, more on anonymous methods and such non-trivial thing as closure:
What are Anonymous Types in C#?[^],
Looping for creating new thread give some problem[^],
http://en.wikipedia.org/wiki/Closure_%28computer_science%29[^].

—SA


这篇关于通用事件处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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