1

私はこの静的関数を持っています

public static object Create(Type t)
{
    //unimportant
}

上記の関数を制御できないため、変更できません。問題はジェネリックではないため、返されたオブジェクトを何らかの型にキャストする必要があります。この型は、メソッドを呼び出した別のジェネリック クラスの制約によって提供されます。Create

これは私が到達した場所です:

public static class Creator<T>
{
    public static void Create()
    {
        var m = typeof(SomeClass).GetMethod("Create");
        var p = Expression.Parameter(typeof(Type));
        var e = Expression.Call(m, p);

        //at this stage I want to create delegate for calling the 'Create' method, 
        //then pass typeof(T) as parameter, get returned object, 
        //and finally cast it to 'T'.

        //for eg, I can do it like this:
        var f = Expression.Lambda<Func<Type, object>>(e, p).Compile();
        Func<T> mainThing = () => (T)f(typeof(T));

        //is there a way I can achieve in one step?
    }
}

上記のアプローチでは、最終的なデリゲートをコンパイルするのではなく、1 ステップ前にコンパイルします。Func<T>コンパイル前にキャストを組み込んで元に戻すにはどうすればよいですか?

4

2 に答える 2

6

あなたは多くの不必要なフープを飛び越えているようです. 式ツリーを使用してこれを行う理由がわかりません。それだけではない理由:

public static class Creator<T>
{
    public static void Create()
    {
        Func<T> mainThing = () => (T)SomeClass.Create(typeof(T));
    }
}

???

メソッド呼び出しの式ツリーを作成して、メソッド呼び出しを行うデリゲートに戻してから呼び出す目的は何ですか? なぜSomeClass.Create直接電話しないのですか?

私がここに欠けているものはありますか?

実際の質問に答えるには:

コンパイル前にキャストを組み込むにはどうすればよいですか?

Expression.Convert()変換を表す式ツリー ノードを作成するために使用します。

于 2013-04-23T17:12:16.870 に答える
2

への呼び出しが必要であり、 の代わりに aExpression.Convertを使用すると思います:ConstantExpressionParameterExpression

var method = typeof(SomeClass).GetMethod("Create");
var call = Expression.Call(method, Expression.Constant(typeof(T), typeof(Type)));
var conversion = Expression.Convert(call, typeof(T));
var function = Expression.Lambda<Func<T>>(conversion).Compile();

(テストはしていませんが、大丈夫そうです...)

于 2013-04-23T17:10:28.737 に答える