. net生成泛型方法
本文关键字:泛型方法 net | 更新日期: 2023-09-27 18:13:42
我想订阅一堆通用事件,并使它们都调用一个非通用方法。下面是我的代码:
public delegate void PropertyChangedDelegate<OwnerType, PropertyType>(OwnerType sender, PropertyType oldValue, PropertyType newValue);
public class EventObject
{
public event PropertyChangedDelegate<Object, Boolean> PropertyChanged;
public event PropertyChangedDelegate<Object, Int32> XChanged;
}
static void Main()
{
EventObject eventObject = new EventObject();
EventInfo eventInfo = eventObject.GetType().GetEvent("PropertyChanged");
eventInfo.AddEventHandler(eventObject, PropertyChanged);
}
static void PropertyChanged(Object obj, Object oldValue, Object newValue)
{
}
显然这不起作用,是否有任何方法来做包装器泛型方法?
问题是,PropertyChanged
方法不是逆变的PropertyChangedDelegate
类型,因为发送bool
作为object
需要装箱,所以很明显,你不能使委托与所有事件普遍工作。解决方案是将静态方法编写为"着陆方法"。下面是我的解决方案:
using System;
using System.Reflection;
public delegate void PropertyChangedDelegate<OwnerType, PropertyType>(OwnerType sender, PropertyType oldValue, PropertyType newValue);
public class EventObject
{
public event PropertyChangedDelegate<Object, Boolean> PropertyChanged;
public event PropertyChangedDelegate<Object, Int32> XChanged;
public void RaisePropertyChanged() {
PropertyChanged(this, true, false);
}
}
class Test {
static void Main()
{
EventObject eventObject = new EventObject();
EventInfo eventInfo = eventObject.GetType().GetEvent("PropertyChanged");
Type evType = eventInfo.EventHandlerType;
// replace below with this.GetType() in case of instance method
Type thisType = typeof(Test);
MethodInfo mi = thisType.GetMethod("PropertyChanged", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
MethodInfo genericMi = mi.MakeGenericMethod(evType.GetGenericArguments());
Delegate del = Delegate.CreateDelegate(evType, genericMi);
eventInfo.AddEventHandler(eventObject, del);
// Test
eventObject.RaisePropertyChanged();
}
static void PropertyChanged<TOwner, T>(TOwner obj, T oldValue, T newValue)
{
Console.WriteLine("-- Invoked --");
}
}
灵感来自
使用反射获取静态方法及其参数
和
使用反射创建泛型委托
不能用方法组来代替委托。您可以指定方法匹配的确切委托,如下所示:
EventObject eventObject = new EventObject();
EventInfo eventInfo = eventObject.GetType().GetEvent("PropertyChanged");
eventInfo.AddEventHandler(eventObject, (Action<Object, Object, Object>)PropertyChanged);
但是它仍然会给你运行时异常,因为签名不匹配。
为什么不直接实现+=
?
EventObject eventObject = new EventObject();
eventObject.PropertyChanged += PropertyChanged;
但是由于签名中的类型不匹配,这无法编译。你必须改变委托的签名
public delegate void PropertyChangedDelegate(Object sender, Object oldValue, Object newValue);
或更改事件签名
public event PropertyChangedDelegate<Object, Object> PropertyChanged;
(但这破坏了您拥有强类型委托的所有努力)或更改方法
的签名static void PropertyChanged(Object obj, Boolean oldValue, Boolean newValue)
{
}