2015-09-07 106 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