3

送信時にタイプが未完了のデリゲートに呼び出しを送信するのに問題があります。詳細を説明します。次のデリゲートタイプを宣言しました。

// Delegate type. The 'firstArgument' will be 'this', i.e., this is an open
// instance method: the implicit argument is here given explicitly, in
// 'firstArgument'. (See link below for explanation on open instance delegates).
public delegate Object DirectReadAccessor<T>(T firstArgument);

そして今、私は動的に(つまり、TypeBuilderを使用して)次のクラスを作成しようとしています。

public MyClass {

    // Array of delegates. T has been replaced with MyClass because the
    // argument will be 'this', which is of type MyClass.
    private static DirectReadAccessor<MyClass>[] directReadAccessors;

    // Method that looks up a delegate in the array of delegates and calls it
    // with 'this'.
    public Object DirectRead(int i) {
        directReadAccessors[i](this);
    }

    // Method that is called by the declaring type to pass an array with the
    // MethodInfo of some methods. MyClass then creates delegates for these
    // methods and stores them in the directReadAccessors array.
    public static void InitializeClass(MethodInfo[] directReadAccessorsMInfo) {
        int length = directReadAccessorsMInfo.Length;
        Type[] typeArguments = new Type[] { typeof(MyClass) };
        directReadAccessors = new DirectReadAccessor<MyClass>[length];
        // For each method in directReadAccessorsMInfo...
        for (int i = 0; i < length; i++) {
            // Create a delegate and store it in directReadAccessors.
            directReadAccessors[i] = (DirectReadAccessor<MyClass>)
                   Delegate.CreateDelegate(
                          DirectReadAccessor<MyClass>, // Type of the delegate.
                          null, // Specify null first argument so that it's
                                // *open* instance.
                          directReadAccessorsMInfo[i].MakeGenericMethod(typeArguments) // The method.
                    );
        }
    }

}

*オープンインスタンスデリゲート

DirectReadAccessor []タイプのフィールドdirectReadAccessorsを宣言しようとしたとき、またはまだ存在しないMyClassを再び使用するメソッドInitalizeClassを発行したときに、MyClassが存在しないため、これは注意が必要です。私が作成しているもの)。しかし、私はこれをすべて行うことができましたが、スタックにデリゲートを配置した後、デリゲートを呼び出す方法がわからないため、DirectReadメソッドで問題が発生しています。どうやら私が必要としているのは次の放出です:

ilGenerator.Emit(OpCodes.Callvirt, invokeMInfo);

ここで、invokeMInfoはDirectReadAccessorのInvokeメソッドであり、次のように取得する必要があります。

MethodInfo invokeMInfo = typeof(DirectReadAccessor<MyClass>).GetMethod(
        "Invoke",                        // Name of the method.
        BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, // Binding attributes.
        null,                            // Binder.
        new Type[] { typeof(MyClass) },  // Types of the arguments.
        null                             // Modifiers for the arguments.
);

繰り返しますが、問題はMyClassもDirectReadAccessorもまだ存在しないことです。MyClass用のTypeBuilderと、次のように作成した未完成のDirectReadAccessorタイプがあります。

directReadAccessorType = typeof(DirectReadAccessor<>).MakeGenericType(typeBuilder);

しかし、上記のようにdirectReadAccessorTypeでGetMethod( "Invoke"、....)を呼び出そうとすると、未完了の型のメソッドInvokeを取得できないため、NotSupportedExceptionが発生します。タイプを次のように確定した後、同じ呼び出しを行うことによって、この仮定をテストしました。

typeBuilder.CreateType();

そして確かに、その場合は例外はありません。ただし、InitializeClassのコードを出力している間、型を確定する前にInvokeメソッドのMethodInfoを取得できる必要があります。

これは奇妙な状況です。必要なときにデリゲートを用意しますが、それを呼び出すためのコードを作成できません。誰かが助けを提供できますか?

どうもありがとう、そして長い投稿をお詫びします。

4

3 に答える 3

4

それは難しい問題です。私はあなたがあなたが必要とするものTypeBuilder.GetMethodを手に入れるために使うことができるべきだと思いますMethodInfo

TypeBuilder.GetMethod(directReadAccessorType, 
    typeof(DirectReadAccessor<>).GetMethod("Invoke"));
于 2010-03-03T20:21:08.340 に答える
0

ジェネリックコードをコンパイルし、ILDASMを使用してそれを調べようとしましたか?それはあなたに正しいILとうまくいけば生成するための正しい放出を示すはずです。

于 2010-03-03T09:14:27.890 に答える
0

生成されたクラスのコードの量を最小限に抑えることは理にかなっていますか?

つまり、生成されたクラスは、そのデータへのアクセスを提供するインターフェイスを実装できるということです。これにより、ILの代わりにC#でコーディングできる追加機能を実装できます。

于 2010-03-03T11:01:17.160 に答える