アプリ(WPFでGUI)を作成していてC#の言語的基礎知識を確認する必要があり整理してみました。
あくまで筆者の学習している内容ですので、誤り勘違い等があるかもしれませんが、ご了承ください。
オブジェクトのライフサイクル
ライフサイクルという言葉はスマホアプリ開発の学習で初めて見たような気がします。
C#のオブジェクト、アプリとうプロセスの中で考えてみると、生成は初期化処理ですし、破棄はGCなので、余りプログラマが意識的に管理する必要性は無さそうです。
一般的に
ローカル変数 … 一時的(スコープ内)
staticメンバー変数 … プロセス(アプリの開始~終了まで)
クラスのメンバー変数 … 所属するクラス
となります。実際破棄されるのはGC任せなので、例えばローカル変数でもスコープを抜けたら即破棄されるかどうかは不明です。しかしながらローカル変数は外からアクセスする術が無い(多分)ので、参照できなければ無いものと同じになるかと思います。
staticのメンバー変数は、初期化したタイミングからアプリの終了まで存在していて、グローバル変数の様に使えると考えて良いでしょう。逆に大きなリソースが居座り続けると困る場合が考えられるので、何にでも使えるというわけでは無いと、なります。
一番理解が難しいのがクラスのメンバー変数。所属するクラスの初期化と破棄のタイミングが同じになるという事。ただ、よくよく考えると、最長でstaticメンバー変数と同じ寿命を持つ可能性があるので、使い方次第。
メモリーは限りあるリソースなので不要になったらオブジェクトを破棄しメモリを解放するのが好ましい。その解放をGCで自動化していることに成るので、基本的にプログラマは初期化する場所だけ意識すれば良い。そして、スコープが狭い(ローカル<クラス変数<static変数)ほど、GCで解放される確率が高くなるので、優先順位のそれに倣う方が良さそうです。
また、IDisposableなオブジェクトはusingを使い、意図的に初期化と解放をコントロールするようにします。出来ればusingが使えるようにローカル変数にすると良さそうです。
クラスメンバーのアクセス修飾子
アクセス修飾子は、public、protected、privateといった修飾子ことです。
話は少しずれますが、先ほどのローカル変数、staticメンバー変数、クラスメンバー変数が出てきましたが、これらの使われ方として、
ローカル変数 … スコープ内での利用、外からの参照は想定外
staticメンバー変数 … グローバルスコープ。どこからでもアクセス可(publicなら)
クラスのメンバー変数 … クラス内からもアクセスするし、オブジェクトとして外部からもアクセスする。
クラスのメンバー変数はそのまま使うと、自由自在にアクセス出来てしまいます。
アクセスを制限することで事故を未然に防ぎます。
public … 外部・内部・派生先からアクセス可能
private … 内部のみアクセス可能
protected … 内部・派生先からアクセス可能
継承を含むアクセスコントロールとなります。
基本メンバー変数はprivateで良いでしょう。継承をするならprotected。
外部から参照する場合は、メンバー変数をpublicにするより、
プロパティとして公開した方が、
外部参照をきっかけにコードを実行出来て便利です。
まとめ
アプリを作っていて管理する情報をどこに持たせる(所属させる)のが良いのか迷い、基本を見直してみました。
結論として、
IDisposableなオブジェクトはusingを使えるようにローカルスコープにした方が良いぐらいで、
後は、あまり強い制約は無さそう。
protectedとかは継承を使わない限り関係ない話ですし、あとは内部と外部、外部はプロパティが高機能といったぐらいですかね。
あとは関連する方法をクラスのメンバー変数にすべきところではあるのですが、そのクラスのオブジェクトをアプリの初期化処理で生成し、アプリの終了処理で解放するとなると、staticなメンバー変数と寿命的には同じになります。
WPFだと、ApplicationやWindowクラスを継承しそこにアプリケーションのコードを組み立てる形になるので、Applicationクラスに所属させてアプリと同じライフサイクルにするか、シングルウィンドウのアプリなら、Windowクラスに所属させて、ウィンドウが閉じられるまで有効にするかといった感じになります。
オブジェクト指向プログラミングというより、なるべくオブジェクトを使わないプログラミングを心掛けており、どこまでシンプルに出来るか試行錯誤しています。


コメント