2015-09-07 90 views
0

我使用庫[1]限定一些東西我想利用:傳遞一個事件作爲參數

public delegate void FooHandler(int i); 
public delegate void BarHandler(string s); 

public class Foo 
{ 
    public event FooHandler Fooh; 
} 

public class Bar 
{ 
    public event BarHandler Barh; 
} 

我想有一個短期存儲器,我可以「重視」 這些事件:

public class ShortTermMemory<T> 
{ 

    public ShortTermMemory(??? arg) 
    { 
     arg += t => Remeber = t; 
    } 

    public T Remember { get; private set; } 
} 

和地方重視他們像

var foo = new Foo(); 
var bar = new Bar(); 
var intmemory = new ShortTermMemory<int>(foo.Fooh); 
var stringmemory = new ShortTermMemory<string>(bar.Barh); 

這是IM可能是因爲:

  • ???是(有些可以理解的)不是有效的類型聲明,
  • 「事件只能在左手側使用+ =或 - =」

有什麼我可以做,以解決這個問題,或者這在C#中根本不可能?我想有編譯時保證ShortTermMemory僅僅是「喂」由一個事件源,它是在編譯時已知具有類型T.的單個參數

[1]:實施例實施僅用於說明目的

+1

類型的???可以是'FooHandler'或'BarHandler',具體取決於哪一個事件,同樣,因爲編譯器說你不能訪問包含類以外的事件處理程序,除了+ =或 - =。 –

回答

1

編譯時確保您期待在C#中不可能。這裏有幾個問題:

  1. event s由具有組合調用列表的私人委託字段支持。這被認爲是實現細節,因此是私人訪問。
  2. 我們需要引用該事件的委託外地申請addremove+=/-=)運營商Delegate.Combine/Remove
  3. 由於C#將委託作爲自己的類型處理,我們應該有一個FooHandlerBarHandler的通用定義。
  4. 您錯過了該活動的取消訂閱,可能放置在ShortTermMemory`1的析構函數中。此時,事件對象可以不存在了,見How to save a ref variable for later use?
-1
工作

溶液:

public delegate void Handler<T> (T i); 

public class Foo 
{ 
    public event Handler<int> Fooh; 

    public void Set(int i) { 
     if (Fooh != null) { 
      Fooh(i); 
     } 
    } 
} 

public class ShortTermMemory<T> 
{ 
    object obj = null; 
    string eventName; 
    Handler<T> handler; 

    public ShortTermMemory (object obj, string eventName) { 
     this.obj = obj; 
     this.eventName = eventName; 
     this.handler = new Handler<T>(Set); 

     Type type = obj.GetType(); 
     EventInfo info = type.GetEvent(eventName); 

     info.AddEventHandler(obj, handler); 
    } 

    ~ShortTermMemory() { 
     if (obj != null) { 
      Type type = obj.GetType(); 
      EventInfo info = type.GetEvent(eventName); 

      info.RemoveEventHandler(obj, handler); 
     } 
    } 

    public T Remember { get; set; } 

    public void Set(T t) { 
     Remember = t; 
    } 
} 

var foo = new Foo(); 
var intmemory1 = new ShortTermMemory<int>(foo, "Fooh"); 
var intmemory2 = new ShortTermMemory<int>(foo, "Fooh"); 

foo.Set(10); 
+0

我不打算在這一點上維護包含Foo的庫的分支,儘管 – Martijn