0

問題:

  • コード ジェネレーターによって生成された数千のデリゲート フィールドを持つ .Net 2.0 クラス

    1. さまざまな署名
    2. デリゲートは値を返す場合と返さない場合があります
    3. ジェネリックなし
  • これらのデリゲートは、実行時にすばやく初期化する必要があります

    1. デリゲートの初期化は簡単ですが、コストがかかります
    2. ロット全体の初期化コストは現在 300 ミリ秒以下 - 許容範囲ですが、完全ではありません
    3. ユーザーはこれらのデリゲートの 10% 未満しか使用しない可能性があります。これらのデリゲートのみを遅延ロードできれば、はるかに高速になります。(使っていないものにお金はかかりません)

質問:

リフレクションを使用してデリゲート フィールドを遅延初期化することは可能ですか? 擬似コード:

class Delegates
{
    int FooDelegate(IntPtr p1, float* p2);
    public static FooDelegate Foo;
    // Several thousand more    
    ...

    static Delegate LoadDelegate(string name, Type signature)
    {
        // complex and expensive p/invokes
    }

    static void SetupStubs()
    {
        // Create loader stubs (using reflection because
        // JIT times are prohibitive when done inline)
        foreach (FieldInfo f in typeof(Delegates)
            .GetFields(BindingFlags.Static | BindingFlags.NonPublic))
        {
            // We need to generate a compatible delegate, which:
            // (a) calls LoadDelegate("Foo", typeof(FooDelegate)), and
            // (b) assigns its result to the Foo field (replacing the stub),
            // (c) executes Foo(p1, p2) and returns the result, where 
            // p1 and p2 are the original parameters specified by the user.
            Delegate stub = ...;
            f.SetValue(null, stub);
        }
    }
}

(a)、(b)、および (c) を実行するスタブを作成すること可能であると感じていますが、その方法を推測することはできませんでした。

理想的には、コードは .Net 2.0 および Mono 2.0 を実行し、System.Reflection.Emit を使用しないようにする必要があります。ただし、.Net 3.5 または DynamicMethod を使用したソリューションにも興味があります。

何か案は?:)

4

1 に答える 1

1

はい、実行時にスタブを動的に生成することは可能ですが、300 ミリ秒以上かかる可能性が非常に高く、何千ものスタブの生成について話しているのです。ところで、それには DynamicMethods またはおそらく 3.5 Expressions が必要です。

最善の方法は、コンパイル前にスタブを生成することです。理想的には、フィールドを生成するコード ジェネレーターもスタブを生成する必要があります。既存のコード ジェネレーターを変更できない場合は、T4 などのテンプレート エンジンを使用することをお勧めします。

于 2009-10-21T10:48:44.293 に答える