0

私は、デリゲート型と型のデリゲートを受け取り、指定さAction<Object[]>れた型の動的関数を作成する関数に取り組んでいます。この関数は、呼び出された場合、すべての引数を指定されたアクション ハンドルに渡します。

    public static T GetEventDelegate<T>(Action<Object[]> handler) where T : class
    {
        if (!typeof(T).IsSubclassOf(typeof(Delegate)))
            throw new Exception("T must be a delegate type");

        Type[] argTypes = typeof(T).GetMethod("Invoke").GetParameters().Select((para) => para.ParameterType).ToArray();

        List<ParameterExpression> lstArgs = new List<ParameterExpression>(
            argTypes.Select((arg)=>Expression.Parameter(arg))    
        );

        ParameterExpression result = Expression.Variable(typeof(Object[]));

        var assignExpression = Expression.NewArrayInit(typeof(Object),lstArgs.ToArray());

        var callExpression = Expression.Call(handler.Method, result);

        var block = Expression.Block(
            new List<ParameterExpression>(){result},
            new Expression[]{assignExpression,callExpression}
        );

        var del = Expression.Lambda(block, lstArgs.ToArray()).Compile();

        return Delegate.CreateDelegate(typeof(T), del, "Invoke") as T;
    }

    private static void testDel()
    {
        var del = GetEventDelegate<EventHandler>(
            (x) =>
            {
                //Error, because x == null
                Debug.Print(x.ToString());
            }
       );
        del("testString", new EventArgs());
    }

残念ながら、アクション ハンドラはnull値しか渡されません (「参考文献」を参照testDel())。

エラーを見つけるのを手伝ってくれませんか?

前もって感謝します!

4

1 に答える 1

1

あなたの問題は、結果の ParameterExpression を Object 型として初期化するが、実際には値を割り当てないためです。これが(コンパイルを呼び出した後)にコンパイルされるのは、次のとおりです。

void Func(arguments..)
{
   Object result;
   new object[](arguments...);
   method(result);
}

割り当て式を使用して、実際に配列を結果に割り当てることはありません。

問題とは関係ありませんが、ジェネリックの型を持っているため、ラムダを作成するときに Expression.Lambda() を使用できます。

于 2012-06-27T13:46:02.007 に答える