这已经证明是一个非常冗长的问题,所以请提前感谢所有放弃阅读和评论/回答的人:)
我使用通过接口实现的观察者模式:
public interface IObserver<in T>where T:EventArgs
{
void Update(object sender, T e);
}
public interface ISubject<in T, TU>where TU:EventArgs
{
event EventHandler<TU> Notify;
T State { set; }
void Attach(Action<object,TU> callback);
void Detach(Action<object, TU> callback);
}
我创建了两个实现这些接口的简单类
在MyObserver
对象中引发Notify
事件时,MySubject
对象只会将一个字符串输出到控制台窗口。
public class MyObserver:IObserver<TestEventArgs>
{
private ISubject<bool, TestEventArgs> _subject;
public MyObserver(ISubject<bool, TestEventArgs> subject)
{
_subject = subject;
}
public void Subscribe()
{
_subject.Attach(Update);
}
public void Unsubscribe()
{
_subject.Detach(Update);
}
public void Update(object sender, TestEventArgs e)
{
Console.WriteLine(e.TestMessage);
}
}
public class MySubject:ISubject<bool, TestEventArgs>
{
public void ObservableEvent(string message)
{
InvokeNotify(message);
}
private void InvokeNotify(string message)
{
EventHandler<TestEventArgs> handler = Notify;
if(handler != null)
{
handler(this, new TestEventArgs(message));
}
}
public event EventHandler<TestEventArgs> Notify;
public bool State
{
set { throw new NotImplementedException(); }
}
public void Attach(Action<object, TestEventArgs> callback)
{
Notify += new EventHandler<TestEventArgs>(callback);
}
public void Detach(Action<object, TestEventArgs> callback)
{
Notify -= new EventHandler<TestEventArgs>(callback);
}
}
public class TestEventArgs:EventArgs
{
public TestEventArgs(string message)
{
TestMessage = message;
}
public string TestMessage { get; private set; }
}
此测试程序显示:
myObserver
订阅该事件之前,没有消息输出到控制台窗口。myObserver
订阅了Notify
事件后,该消息将输出到控制台窗口。 myObserver
从Notify
事件取消订阅后,消息仍会输出到控制台窗口
static void Main(string[] args)
{
MySubject mySubject = new MySubject();
MyObserver myObserver = new MyObserver(mySubject);
//we have not subscribed to the event so this should not be output to the console
mySubject.ObservableEvent("First Test");
myObserver.Subscribe();
//we are now subscribing to the event. This should be displayed on the console window
mySubject.ObservableEvent("Second Test");
myObserver.Unsubscribe();
//We have unsubscribed from the event. I would not expect this to be displayed
//...but it is!
mySubject.ObservableEvent("Third Test");
Console.ReadLine();
}
问题我遇到的是取消订阅流程无效。
我真的不明白为什么。
Contains
方法始终返回false
的原因。答案 0 :(得分:1)
我怀疑你的问题是这段代码:
public void Attach(Action<object, TestEventArgs> callback)
{
Notify += new EventHandler<TestEventArgs>(callback);
}
实际上分配一个新对象,相应的Detach
代码也是如此。所以分离的东西与所附的东西不同。
我不确定,但您可以通过更改Attach
和Detach
来修复它,以便它们可以:
void Attach(EventHandler<TU> callback);
void Detach(EventHandler<TU> callback);
在客户端代码中:
public void Attach(EventHandler<TestEventArgs> callback)
{
Notify += callback;
}
public void Detach(EventHandler<TestEventArgs> callback)
{
Notify -= callback;
}
我实际上并没有尝试编译它,但它看起来应该可以工作。
或者,如果编译器可以进行类型转换:
public void Attach(Action<object, TestEventArgs> callback)
{
Notify += callback;
}
可能值得一试。