. 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)
    {
    }

显然这不起作用,是否有任何方法来做包装器泛型方法?

. net生成泛型方法

问题是,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)
{
}