これは非常に長い質問であることが判明したので、それを読んでコメント/回答する時間をあきらめたすべての人に事前に感謝します:)
編集
- この質問は大幅に簡略化されています。
- サンプルコードは完全でシンプルなプログラムになりました
インターフェイスを介して実装されたオブザーバーパターンを使用し
ています。
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);
}
これらのインターフェイスを実装する2つの単純なクラスを作成しました。オブジェクトでイベントが発生すると、オブジェクトは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(); }
私が抱えている問題は、購読解除プロセスが機能していないことです。
理由がよくわかりません。
質問
- 登録解除プロセスが機能しないのはなぜですか?
- 2つのイベントハンドラーを比較するとどうなりますか?それらはどのように等しいかどうかと定義されていますか?
Contains
これは、呼び出しリストメソッドが常にを返す理由に対する答えにつながる可能性がありますfalse
。