5

適切なホイールがどのように回転するかを理解できるように、ホイールを部分的に再発明して遊んでいます。

型のデフォルトコンストラクターをコンパイルして返すためのこのジェネリック関数を検討してください。

public static Func<TConcrete> Creator<TConcrete>()
{
    // All checking removed for brevity
    var ctor = typeof(TConcrete).GetConstructor(new Type[0]);
    var lambda = Expression.Lambda<Func<TConcrete>>(Expression.New(ctor));
    return lambda.Compile();
}

これにより、渡された型をインスタンス化するために使用できる、型付きのデリゲートが返されると思います。

ここで、さまざまなタイプのセットに対してこれを実行する関数が必要だと考えてください。どうすればよいでしょうか。私は...の線に沿ってthikingしていました

public static IEnumerable<Delegate> Creators(IEnumerable<Type> types)
{
    foreach (var type in types)
    {
        var ctor = type.GetConstructor(new Type[0]);
        var lamda = Expression.Lambda<Func<????>>(Expression.New(ctor));
        yield return lambda.Compile();
    }
}

これからわか​​るように、????これは私が立ち往生した場所です。これを行う方法はありますか、それとも私のアプローチに欠陥がありますか?

4

2 に答える 2

7

デリゲートタイプを:Expression.Lambdaとして取る別の呼び出しを使用できます。Type

Type delegateType = typeof(Func<>).MakeGenericType(type);
var lambda = Expression.Lambda(delegateType, Expression.New(ctor));
yield return lambda.Compile();

このオーバーロードは-ではなくLambda非ジェネリック型を返すことに注意してください。ただし、ここで必要なのは、を返すメソッドを公開することです。基本的には、「既知のデリゲート型」コードで恩恵を受けるコンパイル時の型チェックの一部を回避するだけです。LambdaExpressionExpression<TDelegate>CompileDelegate

于 2012-06-21T16:59:03.907 に答える
6

非ジェネリックオーバーロードをMakeGenericType:と組み合わせて使用​​します。

var lamda = Expression.Lambda<Func<????>>(Expression.New(ctor));

次のようになります。

var funcType = typeof(Func<>).MakeGenericType(type);
var lamda = Expression.Lambda(funcType, Expression.New(ctor));
于 2012-06-21T16:57:34.870 に答える