我使用库 [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);
这是不可能的,因为:
我能做些什么来解决这个问题,或者在C#中根本不可能做到这一点?我希望编译时保证ShortTermMemory
只是&#34;馈送&#34;通过一个事件源,在编译时已知有一个类型为T的参数。
[1]:仅用于演示目的的示例实现
答案 0 :(得分:1)
使用编译时保证您期望它在C#中不可能。那里有一些问题:
event
由私有委托字段支持,该字段具有组合的调用列表。这被视为实现细节,因此是私有访问。add
和remove
(+=
/ -=
)运算符应用于Delegate.Combine
/ { {1}}。Remove
和FooHandler
都有一个通用的定义。BarHandler
的析构函数中。目前,事件对象可能不再存在,请参阅How to save a ref variable for later use? 答案 1 :(得分:-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);