3

私は動的に C# 型初期化子のようなものを構築しようとしています:

MyClass class = new MyClass { MyStringProperty= inputString };

特定の型を一度反映し、クラスの新しいインスタンスを作成して入力パラメーターに基づいてデータを設定するデリゲートを返すジェネリック メソッドを作成したいと考えています。メソッドのシグネチャは次のようになります。

Func<string,T> CreateFunc<T>();

結果の関数を呼び出すと、(たとえば) 入力文字列引数の値に対する String 型のすべてのパブリック プロパティを持つ 'T' の新しいインスタンスが作成されます。

したがって、「MyClass」に MyStringProperty のみがあると仮定すると、以下のコードは最初のコードと機能的に同等になります。

var func = CreateFunc<MyClass>();
func.Invoke(inputString);

私は System.Reflection および System.Linq.Expressions 名前空間にかなり精通しており、過去にこのような適度に複雑なことをいくつか行ったことがありますが、これには困惑しています。リフレクションを使用してプロパティを単純に反復するのではなく、コンパイルされたデリゲートを構築したいと考えています。

ありがとう!

4

3 に答える 3

1

ええと、そうです、私は自分自身にとって物事を複雑にしすぎていました。これは私が探していた方法です:

public static Func<string, T> CreateFunc<T>()
    where T : class
{
    var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty);
    var param = Expression.Parameter(typeof(string),"o");
    var constructorInfo = typeof(T).GetConstructor(new Type[] { });
    List<MemberBinding> bindings = new List<MemberBinding>();
    foreach (var property in properties)
        bindings.Add(Expression.Bind(property, param));

    var memberInit = Expression.MemberInit(Expression.New(constructorInfo), bindings);

    var func = Expression.Lambda<Func<string, T>>(memberInit, new ParameterExpression[] {param}).Compile();

    return func;            
}
于 2010-02-19T19:54:23.323 に答える
1

CLR 4.0 では、式を使用して完全なステートメントを作成できます。

それまでは、コード生成ジョブを見ています。プロトタイプを作成する最も簡単な方法は、StringBuilder で C# をビルドし、その上でコンパイラを呼び出すことです。キャッシュを使用すると、正常に実行されます。

これを行うためのハードコアな方法は、IL を生成し、Reflection Emit を使用してメソッドをビルドすることです。これにより、コンパイラへの呼び出しが回避されます。

于 2010-02-19T19:26:57.603 に答える
0

残念ながら、私はこれが起こっているのを見ていませんが、表現やデリゲートで実行できる深いvodooに関しては、私は専門家ではありません。

私の見方では、これはリフレクションでのみ行うことができます。反映しない場合は、コンパイル時に、設定する各プロパティの名前を知る必要があります。サポートしたい個別のクラスごとに個別の関数を実行することもできますが、それは一般的な万能関数の要件に反しているようです。

そもそもなぜ機能なのか聞いてもいいですか?何らかの形の依存性注入?

于 2010-02-19T19:30:00.263 に答える