C#/いまさらヒトに聞けないこといろいろ/弱参照
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
// 下階層用テンプレート
#topicpath
----
//ここにコンテンツを記述します。
#contents
**概要 [#p3de5dc1]
たとえばGUIアプリケーションで、いろいろなウィンドウが...
interface Observer { void update(); }
ってインタフェースと、イベント発生時にイベントをObserver...
class Subject
{
private IList<Observer> observers = new List<Observer>...
public void notifyObservers()
{
foreach (var observer in observers)
{
observer.update();
}
}
public void addObserver(Observer observer){ observers....
public void removeObserver(Observer observer) { observ...
}
を作成したりします。んで、それぞれのウィンドウクラスが、...
あ、C#だったらObserverインタフェースとかじゃなくてdelegat...
**まずはベタに基本を作ってみる [#gf0926f6]
さて、各ウィンドウが登録したObserverなインスタンスは、そ...
まずは弱参照をつかわないでベタにこんな感じ。フィールドにO...
abstract class IWindow
{
public Subject Subject { get; set; }
public IWindow(Subject subject)
{
this.Subject = subject;
}
public abstract void init();
}
class MyWindow : IWindow
{
private Observer observer;
public MyWindow(Subject subject, String name)
: base(subject)
{
observer = new MyObserver(name);
}
public override void init()
{
base.Subject.addObserver(observer);
}
}
class MyObserver : Observer
{
private String name;
public MyObserver(String name){this.name = name;}
public void update()
{
Console.WriteLine(name + " にイベントが通知されまし...
}
}
メインクラスはこんな感じ。
class Program
{
public static void Main(string[] args)
{
Subject subject = new Subject();
// Observerを持ったウィンドウクラスを作成。
IWindow window1 = new MyWindow(subject, "ウィンドウ...
window1.init();
IWindow window2 = new MyWindow(subject, "ウィンドウ...
window2.init();
// なんかイベントが発生したとかで、subjectがObserver...
subject.notifyObservers();
window1 = null; //ウィンドウ1への参照がなくなったの...
GC.Collect();
subject.notifyObservers();
}
}
途中でwindow1をnullにしてウィンドウ1への参照がなくなって...
ウィンドウ1 にイベントが通知されました
ウィンドウ2 にイベントが通知されました
ウィンドウ1 にイベントが通知されました
ウィンドウ2 にイベントが通知されました
ってウィンドウ1のイベントハンドラが呼び出されてしまいま...
**で弱参照を使うとどうなるか [#q0e7aeef]
さて先のプログラムを弱参照を使って書き替えてみます。弱参...
WeakReference reference = new WeakReference(observer, fa...
こうすると、observerの先のオブジェクトがそのほかのインス...
この弱参照を使って実際に Subject クラスを書き替えてみます。
class Subject
{
private IList<WeakReference> observers = new List<Weak...
public void notifyObservers()
{
foreach (var observer in observers)
{
Observer observerTarget = (Observer)observer.Target;
if (observerTarget != null)
{
observerTarget.update();
}
else
{
Console.WriteLine("このObserverは削除されたよう...
}
}
}
public void addObserver(Observer observer) { observer...
//↑参照をWeakReference経由に書き替えました
public void removeObserver(Observer observer) {observe...
}
これで実行してみます。
ウィンドウ1 にイベントが通知されました
ウィンドウ2 にイベントが通知されました
このObserverは削除されたようです
ウィンドウ2 にイベントが通知されました
となりました。window1をnullにしてGCさせたら、ウィンドウ1...
Observer observerTarget = (Observer)observer.Target;
って取りだそうとしたときにnullになりました。これってよう...
**delegateでもやってみる [#j3f3ce48]
さて、Observerインタフェースを用いたWeakReferenceの動きは...
JavaならこれでOKです、つぎはC#のdelegateはどうなるかやっ...
コードは下記の通りになりました
public delegate void UpdateHandler();
//interface Observer { void update(); }
//class MyObserver : Observer
class Subject
{
private IList<WeakReference> observers = new List<Weak...
public void notifyObservers()
{
foreach (var observer in observers)
{
// 変数をObserverからdelegateへ変更。
UpdateHandler observerTarget = (UpdateHandler)obse...
if (observerTarget != null)
{
observerTarget();
}
else
{
Console.WriteLine("このObserverは削除されたよう...
}
}
}
//add/removeも型をdelegateへ変更
public void addObserver(UpdateHandler observer)
{
observers.Add(new WeakReference(observer, false));
}
public void removeObserver(UpdateHandler observer)
{
observers.Remove(new WeakReference(observer, false));
}
}
class MyWindow : IWindow
{
public String name { get; set; }
private UpdateHandler observer;
public MyWindow(Subject subject, String name)
: base(subject)
{
observer = new UpdateHandler(update);
this.name = name;
}
public override void init()
{
base.Subject.addObserver(observer);
}
public void update()
{
Console.WriteLine(name + " にイベントが通知されまし...
}
}
実行してみると先ほどと同じ結果が得られます。つまりWeakRef...
----
この記事は
#vote(おもしろかった[5],そうでもない[0])
#comment
#topicpath
SIZE(10){現在のアクセス:&counter;}
終了行:
// 下階層用テンプレート
#topicpath
----
//ここにコンテンツを記述します。
#contents
**概要 [#p3de5dc1]
たとえばGUIアプリケーションで、いろいろなウィンドウが...
interface Observer { void update(); }
ってインタフェースと、イベント発生時にイベントをObserver...
class Subject
{
private IList<Observer> observers = new List<Observer>...
public void notifyObservers()
{
foreach (var observer in observers)
{
observer.update();
}
}
public void addObserver(Observer observer){ observers....
public void removeObserver(Observer observer) { observ...
}
を作成したりします。んで、それぞれのウィンドウクラスが、...
あ、C#だったらObserverインタフェースとかじゃなくてdelegat...
**まずはベタに基本を作ってみる [#gf0926f6]
さて、各ウィンドウが登録したObserverなインスタンスは、そ...
まずは弱参照をつかわないでベタにこんな感じ。フィールドにO...
abstract class IWindow
{
public Subject Subject { get; set; }
public IWindow(Subject subject)
{
this.Subject = subject;
}
public abstract void init();
}
class MyWindow : IWindow
{
private Observer observer;
public MyWindow(Subject subject, String name)
: base(subject)
{
observer = new MyObserver(name);
}
public override void init()
{
base.Subject.addObserver(observer);
}
}
class MyObserver : Observer
{
private String name;
public MyObserver(String name){this.name = name;}
public void update()
{
Console.WriteLine(name + " にイベントが通知されまし...
}
}
メインクラスはこんな感じ。
class Program
{
public static void Main(string[] args)
{
Subject subject = new Subject();
// Observerを持ったウィンドウクラスを作成。
IWindow window1 = new MyWindow(subject, "ウィンドウ...
window1.init();
IWindow window2 = new MyWindow(subject, "ウィンドウ...
window2.init();
// なんかイベントが発生したとかで、subjectがObserver...
subject.notifyObservers();
window1 = null; //ウィンドウ1への参照がなくなったの...
GC.Collect();
subject.notifyObservers();
}
}
途中でwindow1をnullにしてウィンドウ1への参照がなくなって...
ウィンドウ1 にイベントが通知されました
ウィンドウ2 にイベントが通知されました
ウィンドウ1 にイベントが通知されました
ウィンドウ2 にイベントが通知されました
ってウィンドウ1のイベントハンドラが呼び出されてしまいま...
**で弱参照を使うとどうなるか [#q0e7aeef]
さて先のプログラムを弱参照を使って書き替えてみます。弱参...
WeakReference reference = new WeakReference(observer, fa...
こうすると、observerの先のオブジェクトがそのほかのインス...
この弱参照を使って実際に Subject クラスを書き替えてみます。
class Subject
{
private IList<WeakReference> observers = new List<Weak...
public void notifyObservers()
{
foreach (var observer in observers)
{
Observer observerTarget = (Observer)observer.Target;
if (observerTarget != null)
{
observerTarget.update();
}
else
{
Console.WriteLine("このObserverは削除されたよう...
}
}
}
public void addObserver(Observer observer) { observer...
//↑参照をWeakReference経由に書き替えました
public void removeObserver(Observer observer) {observe...
}
これで実行してみます。
ウィンドウ1 にイベントが通知されました
ウィンドウ2 にイベントが通知されました
このObserverは削除されたようです
ウィンドウ2 にイベントが通知されました
となりました。window1をnullにしてGCさせたら、ウィンドウ1...
Observer observerTarget = (Observer)observer.Target;
って取りだそうとしたときにnullになりました。これってよう...
**delegateでもやってみる [#j3f3ce48]
さて、Observerインタフェースを用いたWeakReferenceの動きは...
JavaならこれでOKです、つぎはC#のdelegateはどうなるかやっ...
コードは下記の通りになりました
public delegate void UpdateHandler();
//interface Observer { void update(); }
//class MyObserver : Observer
class Subject
{
private IList<WeakReference> observers = new List<Weak...
public void notifyObservers()
{
foreach (var observer in observers)
{
// 変数をObserverからdelegateへ変更。
UpdateHandler observerTarget = (UpdateHandler)obse...
if (observerTarget != null)
{
observerTarget();
}
else
{
Console.WriteLine("このObserverは削除されたよう...
}
}
}
//add/removeも型をdelegateへ変更
public void addObserver(UpdateHandler observer)
{
observers.Add(new WeakReference(observer, false));
}
public void removeObserver(UpdateHandler observer)
{
observers.Remove(new WeakReference(observer, false));
}
}
class MyWindow : IWindow
{
public String name { get; set; }
private UpdateHandler observer;
public MyWindow(Subject subject, String name)
: base(subject)
{
observer = new UpdateHandler(update);
this.name = name;
}
public override void init()
{
base.Subject.addObserver(observer);
}
public void update()
{
Console.WriteLine(name + " にイベントが通知されまし...
}
}
実行してみると先ほどと同じ結果が得られます。つまりWeakRef...
----
この記事は
#vote(おもしろかった[5],そうでもない[0])
#comment
#topicpath
SIZE(10){現在のアクセス:&counter;}
ページ名: