c# - 获取匿名方法的目标

标签 c# .net delegates anonymous-methods anonymous-delegates

以下方法是基类的一部分,它使派生类能够指定应由事件通知谁。

  protected void RaiseEvent<TEventArgs>(EventHandler<TEventArgs> updateEvent, TEventArgs eventArgs, UpdateReceivers updateReceivers) 
     where TEventArgs : EventArgs
  {
     EventHandler<TEventArgs> handler = updateEvent;
     if (handler != null)
     {
        if (updateReceivers.ToAllSubscribers)
        {
           handler(this, eventArgs);
        }
        else
        {
           NotifySpecifiedReceiver(handler, eventArgs, updateReceivers.Receiver);
        }
     }
  }

  private void NotifySpecifiedReceiver<TEventArgs>(EventHandler<TEventArgs> handler, TEventArgs eventArgs, object updateReceiver)
     where TEventArgs : EventArgs
  {
     foreach (Delegate @delegate in handler.GetInvocationList())
     {
        // is the delegates target our receiver?
        // but this doesnt work for anonymous methods :(
        if (@delegate.Target == updateReceiver)
        {
           try
           {
              @delegate.DynamicInvoke(this, eventArgs);
           }
           catch (Exception ex)
           {
           }
        }
     }
  }

为了只通知特定的接收者,方法是这样使用的:(接收者当然必须订阅)

event EventHandler<SomethingChangedEventArgs> SomethingChanged;

RaiseEvent(SomethingChanged, args, UpdateReceivers.Single(receiver));

这只会引发委托(delegate)“指向”接收者。

我的问题是,当我使用匿名方法订阅 SomethingChanged 事件时,当我使用此事件通知订阅它的对象时,它不起作用。

class EventConsumer
{
   private EventSource _eventSource;

   private void SubscribeEvents()
   {
       // ReactOnEvent() will not be called because the check [@delegate.Target == updateReceiver] doesnt work for anonymous methods
       _eventSource.MyStateChanged += (sender, e) => ReactOnEvent();

       _eventSource.PublishCurrentState(this);
   }
}

class EventSource
{
    // multiple objects are subscribed to this event
    event EventHandler<MyStateChangedEventArgs> MyStateChanged;

    public void GetCurrentState(object receiver)
    {
        // receiver ask for the current state, only raise event for him
        RaiseEvent(MyStateChanged, args, UpdateReceivers.Single(receiver));
    }
}

是否有可能获取包含匿名方法的实例?还是我应该使用完全不同的方法来解决我的问题?

最佳答案

您(大概)看到了 compiler-generated closure class包含匿名方法使用的变量。
这个类有specifically-named fields从父类引用信息。

您可以使用反射在编译器生成的 DisplayClass 中查找字段(Target 值)名为 <>4__this ,并获取它的值以找到创建委托(delegate)的类的实例。

但是,不要这样做
这依赖于可能随时更改的 C# 编译器的内部行为。

此外,闭包类包含的字段取决于匿名方法所在的位置以及它引用的成员。如果匿名方法不使用类实例,它可能没有 this领域。

关于c# - 获取匿名方法的目标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6834999/

相关文章:

c# - 隐式强制转换对委托(delegate)类型推断的意外影响

c# - 您将如何更改我用 C# 编写的 Heartbeat 进程?

c# - 对实现接口(interface)的对象进行 LINQ 查询

c# - 从 IEnumerable 转换为 IEnumerable<object>

c# - Unity3d:按下鼠标中键围绕屏幕中心旋转相机

.net - 使用 WebDAV 访问 Exchange 2003 收件箱

c# - 解决编译时函数不正确的BUG?

java - 从 Java 中调用具有类委托(delegate)的 Kotlin 对象作为静态方法

c# - 使用 System.Text.Json 进行自定义反序列化

c# - 使用 Entity Framework 6 和 MySql 进行多对多实体更新时, key 'PRIMARY' 出现重复条目​​...