好的,我想使用反射来订阅一个具有通用参数的事件。
当我说“订阅活动”时,我也只想确保使用正确的术语。我的意思是这样的:
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,这是集合中项目的类型)。没有一种对我有用。肯定会更简单,但是我还没有碰到这种方法。
答案 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" );
}