リフレクション出力による動的メソッドのシナリオ

更新 : 2007 年 11 月

DynamicMethod クラス (.NET Framework Version 2.0 で新たに追加) を使用して作成した動的メソッドには、実行時に静的メソッドを出力する拡張機能が用意されています。動的メソッドは、次のような方法で System.Reflection.Emit 名前空間の型の機能を拡張します。

  • メソッドを格納するために、動的アセンブリ、動的モジュール、および動的な型を生成する必要はないため、オーバーヘッドを減らすことができます。

  • メソッドが必要でなくなると、メソッド本体で使用するメモリをクリアできるため、長時間実行されるアプリケーションで、リソース使用量を適切に保つことができます。

  • 十分なセキュリティ アクセス許可が付与されている場合、動的メソッドはコードを既存のアセンブリまたは型に関連付けることができ、そのコードは内部の型またはプライベート メンバと同じ参照範囲を持つことができます。

  • 十分なセキュリティ アクセス許可が付与されている場合、動的メソッドによってコードはジャスト イン タイム (JIT: Just-In-Time) の参照範囲チェックをスキップし、オブジェクトのプライベート データと保護されたデータにアクセスできるようになります。

動的メソッドは、ILGenerator オブジェクトを使用して Microsoft Intermediate Language (MSIL) を出力できます。また、DynamicILInfo オブジェクトを使用して、高機能のクライアントが独自の MSIL の生成を実行できるメタデータ トークンやスコープを使用することもできます。

動的メソッドは、パフォーマンスを向上させるために実行時のコード生成を必要とするシナリオで役立ちます。このセクションでは、シリアル化、オブジェクトとリレーショナル データベース間の対応付け、正規表現、部分評価、ランタイムを必要とする言語のコンパイラの例について説明します。

動的メソッド生成の簡単な例については、「方法 : 動的メソッドを定義および実行する」を参照してください。

遅延バインディングによる呼び出しをサポートする言語

動的メソッドは、コンパイル時にオブジェクトの型がわからないときに、コンパイラ ライタにとって役立ちます。オブジェクトのメンバの呼び出しは実行時に解決する必要があり、多くの場合、引数リストの操作によるオーバーヘッドが伴います。次の Visual Basic コードは、この一例を示しています。

Sub Example(ByVal obj as Object)
    ' ...
    obj.SomeMethod(x, y, z)
    ' ...
End Sub

コンパイラは、SomeMethod を検索し、引数をオブジェクトの配列として準備し、メソッドを呼び出すためのコードを生成する必要があります。InvokeMember メソッドを使用して、リフレクションでこのような呼び出しを実行すると、パフォーマンスが低下します。System.Reflection.Emit 名前空間のメンバを使用して、動的アセンブリ、動的モジュール、動的な型、および動的メソッドを作成することにより、パフォーマンスを向上させることができますが、作業セットのサイズが大きくなり、コードがかなり複雑になる可能性があります。動的メソッドを使用すると、動的アセンブリ、動的モジュール、動的な型を作成する必要がないため、動的メソッド シグネチャが既存のデリゲート型と一致する場合には、より効果的な実装方法が可能になります。この手法は、InvokeMember メソッドを使用するよりもはるかに優れています。この手法は、仮想呼び出しと同様に実行されるわけではありませんが、新しい型が作成されないため、必要となる作業セットのサイズが大幅に縮小されます。さらに、生成された MSIL と関連付けられたネイティブ コードは、必要でなくなったときにクリアできます。

シリアル化

動的メソッドによって、カスタムのシリアル化コードと逆シリアル化コードを記述する必要性をなくすことができます。簡単な規則に従ってシリアル化可能な型をマークし、シリアル化エンジンを使用してその型のメタデータをチェックできます。さらに、必要に応じて適切なシリアライザとデシリアライザを生成し、型のインスタンスで生成したコードを実行できます。

十分なセキュリティ アクセス許可が付与されている場合、動的メソッドを使用して実装されたシリアル化エンジンは、プライベート データや保護されたデータにアクセスし、エンジン作成者が作成していないオブジェクトのシリアル化を有効にできます。

生成されたメソッドを頻繁に使用する場合は、メソッドをキャッシュできます。また、それらのメソッドを簡単に解放することもできます。

部分評価

部分評価は、プログラム特化とも呼ばれ、1 つ以上の入力変数が他の入力よりも時間をかけて変更されるアルゴリズムを最適化するための技法です。部分評価では、変更に時間を要する入力の値を定数のように扱う特殊なメソッド呼び出しを生成することにより、アルゴリズム全体に適用される最適化を強化できます。

この技法を使用すると、多くの場合、低パフォーマンスの汎用アルゴリズムを高パフォーマンスの特殊なアルゴリズムに変換できます。次にいくつかの例を示します。

  • Regex オブジェクトをコンパイルして、特定パターンで一致させるために特化したプログラムを生成する。

  • 特定の型または型のセットをシリアル化および逆シリアル化するために特化したプログラムに、メタデータ駆動型シリアル化エンジンをコンパイルする。

  • XML スキーマをコンパイルして、特定のスキーマを検証するために特化したプログラムを生成する。

  • 特定の方法で XML ドキュメントを変換するために特化したプログラムに XSLT 変換をコンパイルする。

  • 特定のキー用に最適化されたプログラムに、指定したキーを使用してデータを暗号化する汎用の暗号化プログラムをコンパイルする。

動的メソッドを使用すると、実行時に特殊なメソッドを生成して部分評価を実装できます。動的メソッドは、パフォーマンスを向上させるだけでなく、MSIL メソッド本体と JIT コンパイラによって生成された関連するマシン語コードの再利用も可能にします。これは、長時間実行されるプログラムにおいて重要になる場合があります。

これらのシナリオの一部の詳細については、「リフレクション出力のアプリケーション シナリオ」を参照してください。

実行時におけるカスタム ユーザー コードの生成

多くのアプリケーションまたはプラットフォームは、定義済み関数を頻繁に使用して、アプリケーションを実行中にユーザーが記述したカスタム コードを実行できるようにする機能拡張機構を備えています。動的メソッドを使用してこのコードを生成することで、アプリケーションまたはプラットフォームのデザイナは、必要な関数の数を減らし (したがって、メモリの使用量を減らし)、パフォーマンスを犠牲にせずにユーザーに柔軟性を提供できます。

参照

処理手順

方法 : 動的メソッドを定義および実行する

概念

リフレクション出力のアプリケーション シナリオ

参照

DynamicMethod

その他の技術情報

動的メソッドおよびアセンブリの出力