c# - 如何从匿名定义的事件处理程序中提取 "real"目标?

标签 c# anonymous-methods eventhandler

跟进我的问题 here :

根据评论-

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.TargetWhatIsThis.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 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;
    ... 

那么接收器是什么?本地人的值(value)。方法是什么? 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

请不要那样做。事件处理程序的接收者是提供处理程序的代码的实现细节。它不是供您做出决定的。在为事件处理程序生成接收器时,编译器完全有权做出他们喜欢的任何选择,他们确实这样做了。例如,考虑如果事件处理程序是在迭代器 block 或异步方法内创建的,会发生什么情况。或者该事件正在被一些将序列操作应用于该事件的 react 性扩展代码订阅。同样,编译器将在各处生成类。您不能指望类(class)是“明智的”。

您可以依赖的是:订阅者希望在发生某些事情时调用给定的方法。那是你必须遵守的契约;不要试图事后猜测订阅者。

关于c# - 如何从匿名定义的事件处理程序中提取 "real"目标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35759749/

相关文章:

scala - 创建未命名的隐式类或函数

c# - 如何规避在匿名方法 block 中使用 out 参数?

c# - 匿名方法源码

c# - 如何在用户对 gridview 中的列进行排序后保持格式

c# 仅使用方法名称(文本)向事件添加监听器

c# - 无法将 COM 对象转换为 Microsoft.Vbe.Interop.VBE

c# - 保存同名文件

c# - 使用 SqlBulkCopy 时如何检索服务器生成的标识值

c# - 在 MVC + DDD + 存储库模式项目中应用安全性的内容是什么?

c# - 在动态创建的事件处理程序中访问动态创建的控件(文本框)