ずいぶん長いこと、MEFの記事をほったらかしていました。正直自分でも記事書いてたことを忘れてました。ということでリハビリも兼て、次の回のための予備知識であるLazy
遅延初期化
遅延初期化とは読んで字のごとく。初期化を遅延するということです。普通は、初期化といったらこんな感じですよね。
// Hogeというクラスがあると仮定してHogeクラスを初期化する var hoge = new Hoge();
さて、上記のプログラムでHogeクラスの初期化を行いましたが、このhoge変数がいつ使われるのかというのは謎です。その直後に使われるのか?それとも10000行後で使われるのか?それとも特定のボタンが押されるまで出番はないのか?と色々なケースが考えられます。今回の例みたいにHogeクラス1つだったら大して気になりませんが。初期化するオブジェクト数が1000とかになってくると、1つのオブジェクトの初期化処理が10msくらいかかるとして10秒初期化だけでかかってしまいます。そんなとき、ぱっと考え付くのが、必要になったら作ればいいじゃん?という解決策です。
そんなプログラムを書くときに使われるテクニックで以下のようなプログラムを書くこともあったりします。
private Hoge hoge; public Hoge Value { get { if (hoge == null) { // 必要になった段階でインスタンスを作成する hoge = new Hoge(); } return hoge; } }
こんなプログラムを量産するのも疲れるってわけで、遅延初期化をサポートしてくれるクラスが.NET Frameworkには用意されています。Lazyという名前のクラスがそいつになります。ということで早速使ってみましょう。
static void Main(string[] args) { { // この時点ではHogeクラスのインスタンスは作成されない var hoge = new Lazy<Hoge>(); Console.WriteLine("Lazy<Hoge>を作成しました"); // ここで初めてHogeのインスタンスが作成される Console.WriteLine(hoge.Value); } Console.WriteLine("---------------------------------"); { // Hogeの初期化方法もデリゲートで指定可能 var hoge = new Lazy<Hoge>(() => new Hoge(10)); Console.WriteLine("Lazy<Hoge>を作成しました"); // ここで初めてHogeのインスタンスが作成される Console.WriteLine(hoge.Value); } }
使い方は簡単でLazy<遅延初期化したい型>のように書きます。コンストラクタでデリゲートを渡してデフォルトのコンストラクタ以外で初期化したり、初期化時に特定のメソッドを呼んだりとか色々できるようになってます。上記の実行結果を以下に示します。
Lazy<Hoge>を作成しました Hogeが作成されました LazySample.Hoge --------------------------------- Lazy<Hoge>を作成しました Hoge(10)が作成されました LazySample.Hoge
Lazyのインスタンスを初期化したタイミングではなく、LazyのValueプロパティにアクセスしたタイミングで初めてインスタンスが作成されていることがわかります。
これがMEFにどうつながっていくのかというと、プラグインの多いプログラムを作る際に起動時に全部のプラグインを初期化してたら起動処理が凄い時間になってしまうという問題点や、使わないプラグインもメモリ上に乗ってしまうという問題がおきたりします。そういうときにLazyを使うと、プラグインが必要になるタイミングまでインスタンスが作られないという処理が簡単に出来るようになります。
ということで次回は、LazyをMEFで使ってみようと思います。
サンプルコードの入手
コチラからダウンロードできます。
過去の記事
- Managed Extensibility Framework入門 その1「はじめに」
- Managed Extensibility Framework入門 その2「使うに当たって覚えておきたいこと」
- Managed Extensibility Framework入門 その3「Export」
- Managed Extensibility Framework入門 その4「もっとExport」
- Managed Extensibility Framework入門 その5「Import」
- Managed Extensibility Framework入門 その6「拡張可能なアプリケーション作成」
- Managed Extensibility Framework入門 その7「クラス以外のExportとImport」