2013-05-16 34 views
0

我有一堆我想订阅的通用事件,并使它们都调用一个非泛型方法。这里是我的代码:.Net生成通用方法

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

显然这不起作用,有没有办法做一个包装的泛型方法?

+2

启发? – nawfal

回答

1

问题是PropertyChanged方法不逆变到PropertyChangedDelegate类型,因为发送boolobject需要拳,所以很显然,你不能让代表与所有事件普遍工作。解决方法是编写一个静态方法作为“着陆方法”。这里是我的解决方案:

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 --"); 
    } 
} 

为什么使用反射ü这里从

Using Reflection to get static method with its parameters

Create generic delegate using reflection

0

您不能传递方法组代替委托。你可以指定你的方法相匹配的确切委托,像这样:

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

这就是我想要的。