使用通用参数从反射订阅事件

时间:2018-11-03 11:08:51

标签: c# events reflection

好的,我想使用反射来订阅一个具有通用参数的事件。

当我说“订阅活动”时,我也只想确保使用正确的术语。我的意思是这样的:

Mediator.EventMediator.Instance.PopulateItemsEvent += (sender, args) =>
        {
}

我想在你们中领先一些:Stackoverflow上也有类似的问题,我已经阅读了所有可以找到的问题。大多数与没有通用参数的事件或具有通用参数的方法有关。

因此,我有一个名为“ o”的变量,它本身是一个反映的属性,它是一个ObservableCollection。我想从“ o”事件中获取事件(特别是“ CollectionChanged”)。但这是我不知道该怎么做。

为了得到'o',我使用了以下反射:

var o = propertyInfo.GetValue(this, null);

我尝试的第一个建议是“ GetRaisedMethod”,它是EventInfo的属性。

因此,为了获取EventInfo,我使用了以下代码:

EventInfo evi = o.GetType().GetEvent("CollectionChanged", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

'evi'似乎包含正确的信息,但是如果我使用此行:

var invocation = evi.GetRaiseMethod();

我得到空值。但是我已经在浏览过的问题中读到了这件事,这似乎很普遍。即使如此,我还是想尝试一下。

然后我继续讨论另一种方法,在另一个问题中提出该方法是否可行。如下:

var field = typeof(ObservableCollection<>).GetField("CollectionChanged", BindingFlags.NonPublic | BindingFlags.Instance);
var eventDelegate = field.GetValue(o) as MulticastDelegate;

现在,这对我造成了异常,我缩小到这两行的第二行。消息如下:

“不能对类型为Type.ContainsGenericParameters为true的字段执行后期绑定操作。”

所以这就是我认为这是带有通用参数的事件的原因。但是我找不到任何可以解决这个问题的地方。当然,对于方法,可以使用MethodInfo.MakeGenericMethod(),但EventInfo中没有这种东西。

我想要的是能够像平常一样订阅该事件,但是到目前为止,它使我难以理解。

您可能还认为我可以做这样的事情:

(o as ObservableCollection<>).CollectionChanged +=...

但是我不能。我已经尝试了上述所有形式的变体(没有尖括号,带有我自己的类型(类型为Type,这是集合中项目的类型)。没有一种对我有用。肯定会更简单,但是我还没有碰到这种方法。

1 个答案:

答案 0 :(得分:1)

EventInfo.AddEventHandler方法可以为您完成工作,请看以下示例:

public static void Main()
{
    var collection = new ObservableCollection<string>(new [] { "a", "b" });
    var o = (object)collection;

    var eventInfo = o.GetType().GetEvent("CollectionChanged");
    var myEventHandler = new Action<object, NotifyCollectionChangedEventArgs>(( s, a ) => Console.WriteLine(a));
    var del = Delegate.CreateDelegate(eventInfo.EventHandlerType, myEventHandler.Method);

    eventInfo.AddEventHandler(o, del);

    collection.Add( "x" );
}