如何从匿名定义的事件处理程序中提取 "real" 目标?
How can I extract the "real" target from an Event Handler that was defined anonymously?
跟进我的问题 :
根据评论 -
The compiler creates a class member with a fictitious name and attaches it just as you would attach a declared method.
我不完全理解这意味着什么,但我可以验证如果不是说
Foo.Bar += (S, E) => { /*Code Goes Here*/ }
我说
Foo.Bar += FooBar;
private void FooBar( object sender, EventArgs e ){
/*Code Goes Here*/
}
然后 Event.Target
从 WhatIsThis.App.<>c
变为 WhatIsThis.App
。
太棒了,但我不能保证我会始终编写一个实际的方法来附加到事件处理程序。
在我确实使用匿名方法的情况下,有没有办法提取 真实 目标,或者我只是被归类为使用定义的方法(我的意思是,我我猜可以接受,但如果有一些高科技魔法可以用来提取真正的目标,那么我完全赞成。
do not fully comprehend what this means
让我们修正你的理解。假设你有:
class C
{
int x;
void M(int y)
{
int z = GetZ();
Func<int, int> f = q => q + x + y + z;
...
f 是代表。它有一个接收器和一个方法,该方法是接收器的方法。 (请注意,这实际上并不是一个严格的要求,但对于我们今天的目的而言,极端情况是模糊的。)
具有该方法的接收器是什么类型?
能不能是C,接受者等于this
?不,为什么不呢?因为那么我们如何跟踪 y 和 z 的值呢? M 的每次调用都可能有不同的值,因此接收方不能是 this
.
编译器所做的是生成一个新的 class:
class C
{
int x;
class Locals
{
public C __this;
public int y;
public int z;
public int A(int q) { return q + __this.x + y + z; }
}
void M(int y)
{
Locals locals = new Locals();
locals.__this = this;
locals.y = y;
locals.z = GetZ();
Func<int, int> f = locals.A;
...
那么接收器是什么?当地人的价值。方法是什么? A.
当然,Locals 和 A 都被赋予了疯狂的名字,这样你就不会误叫他们。
In the cases where I do use an anonymous method, is there a way to extract the real target
你正在提取真正的接收器,我保证。
'm working on an extension to do some things with Event Handlers and I need to be able to discern what an event handlers target is
请不要那样做。事件处理程序的接收者是提供处理程序的代码的实现细节。它不是供您做出决定的。在为事件处理程序生成接收器时,编译器完全有权做出他们喜欢的任何选择,他们确实这样做了。例如,考虑如果事件处理程序是在迭代器块或异步方法内创建的,会发生什么情况。或者该事件正在被一些将序列操作应用于该事件的反应性扩展代码订阅。同样,编译器将在各处生成 classes。你不能指望 class 是 "sensible".
您可以依赖的是:订阅者希望在发生某些事情时调用给定的方法。那是你必须遵守的契约;不要试图事后猜测订阅者。
跟进我的问题
根据评论 -
The compiler creates a class member with a fictitious name and attaches it just as you would attach a declared method.
我不完全理解这意味着什么,但我可以验证如果不是说
Foo.Bar += (S, E) => { /*Code Goes Here*/ }
我说
Foo.Bar += FooBar;
private void FooBar( object sender, EventArgs e ){
/*Code Goes Here*/
}
然后 Event.Target
从 WhatIsThis.App.<>c
变为 WhatIsThis.App
。
太棒了,但我不能保证我会始终编写一个实际的方法来附加到事件处理程序。
在我确实使用匿名方法的情况下,有没有办法提取 真实 目标,或者我只是被归类为使用定义的方法(我的意思是,我我猜可以接受,但如果有一些高科技魔法可以用来提取真正的目标,那么我完全赞成。
do not fully comprehend what this means
让我们修正你的理解。假设你有:
class C
{
int x;
void M(int y)
{
int z = GetZ();
Func<int, int> f = q => q + x + y + z;
...
f 是代表。它有一个接收器和一个方法,该方法是接收器的方法。 (请注意,这实际上并不是一个严格的要求,但对于我们今天的目的而言,极端情况是模糊的。)
具有该方法的接收器是什么类型?
能不能是C,接受者等于this
?不,为什么不呢?因为那么我们如何跟踪 y 和 z 的值呢? M 的每次调用都可能有不同的值,因此接收方不能是 this
.
编译器所做的是生成一个新的 class:
class C
{
int x;
class Locals
{
public C __this;
public int y;
public int z;
public int A(int q) { return q + __this.x + y + z; }
}
void M(int y)
{
Locals locals = new Locals();
locals.__this = this;
locals.y = y;
locals.z = GetZ();
Func<int, int> f = locals.A;
...
那么接收器是什么?当地人的价值。方法是什么? A.
当然,Locals 和 A 都被赋予了疯狂的名字,这样你就不会误叫他们。
In the cases where I do use an anonymous method, is there a way to extract the real target
你正在提取真正的接收器,我保证。
'm working on an extension to do some things with Event Handlers and I need to be able to discern what an event handlers target is
请不要那样做。事件处理程序的接收者是提供处理程序的代码的实现细节。它不是供您做出决定的。在为事件处理程序生成接收器时,编译器完全有权做出他们喜欢的任何选择,他们确实这样做了。例如,考虑如果事件处理程序是在迭代器块或异步方法内创建的,会发生什么情况。或者该事件正在被一些将序列操作应用于该事件的反应性扩展代码订阅。同样,编译器将在各处生成 classes。你不能指望 class 是 "sensible".
您可以依赖的是:订阅者希望在发生某些事情时调用给定的方法。那是你必须遵守的契约;不要试图事后猜测订阅者。