C#代表和活动?

问题描述 投票:2回答:4

我有一个带有一个类的程序集,该类使用委托和自定义事件args定义了一个自定义事件。现在,我必须通过代码动态加载此程序集,并创建此类的实例。到这里我很好。现在,我必须使用自定义委托为类对象引发的事件提供事件处理程序。如何使用反射将事件处理程序添加到从类引发的事件中?

c# .net
4个回答
3
投票

这是执行此操作的代码:

 class Program
  {
    static void Main(string[] args)
    {
      // Create publisher.
      var pub = Activator.CreateInstance(typeof(Publisher));
      // Get the event.
      var addEvent = typeof(Publisher).GetEvent("Event");

      // Create subscriber.
      var sub = Activator.CreateInstance(typeof(Subscriber));
      // Get the method.
      var handler = typeof(Subscriber).GetMethod("Handle");
      // Create a valid delegate for it.
      var handlerDelegate = MakeEventHandlerDelegate(handler, sub);

      // Add the event.
      addEvent.AddEventHandler(pub, handlerDelegate);

      // Call the raise method.
      var raise = typeof(Publisher).GetMethod("Raise");
      raise.Invoke(pub, new object[] { "Test Value" });
      Console.ReadLine();
    }

    static Delegate MakeEventHandlerDelegate(MethodInfo methodInfo, object target)
    {
      ParameterInfo[] info = methodInfo.GetParameters();
      if (info.Length != 2)
        throw new ArgumentOutOfRangeException("methodInfo");
      if (!typeof(EventArgs).IsAssignableFrom(info[1].ParameterType))
        throw new ArgumentOutOfRangeException("methodInfo");
      if (info[0].ParameterType != typeof(object))
        throw new ArgumentOutOfRangeException("methodInfo");

      return Delegate.CreateDelegate(typeof(EventHandler<>).MakeGenericType(info[1].ParameterType), target, methodInfo);
    }
  }

  class Args : EventArgs
  {
    public string Value { get; set; }
  }

  class Publisher
  {
    public event EventHandler<Args> Event;

    public void Raise(string value)
    {
      if (Event != null)
      {
        Args a = new Args { Value = value };
        Event(this, a);
      }
    }
  }

  class Subscriber
  {
    public void Handle(object sender, Args args)
    {
      Console.WriteLine("Handle called with {0}.", args.Value);
    }
  }

1
投票

事件是多播委托,您将以System.Delegate的类型检索该事件,请使用Delegate.Combine组合两个实例,然后将委托设置为组合的委托。

C#为此具有很好的速记语法:

class SomeClass
{
    public event Action<string> TextEvent;
}

[您可能会这样写:(我有点懒,不会检查,您必须自己解决问题)

var obj = // instance of SomeClass...
var t = typeof(SomeClass); // you need the type object
var member = t.GetEvent("TextEvent"); 
member.AddEventHandler(obj, new Action<string>(delegate(string s)){}); // done!

0
投票

我以前曾经做过,真是太痛苦了-最终遇到了这个tutorial

是否有可能在另一个程序集中有一个接口,您可以使用该接口通过反射连接事件?只是一个想法...


0
投票

我可能会丢失一些内容,但是如果您知道该事件的名称和签名,则需要知道该事件的类型,然后大概知道该事件的类型。在这种情况下,为什么需要使用反射?只要您具有正确键入的引用,就可以按常规方式附加处理程序。

© www.soinside.com 2019 - 2024. All rights reserved.