2013-05-16 58 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) 
{ 
} 

這就是我想要的。