0

SetValueLINQ式を使用してリフレクション->を高速化しようとしています。

私の問題はこの方法です:

public void SetValue<T>(T obj)
{
    FieldInfo field = typeof(T).GetField("Title", BindingFlags.Instance |
                                                  BindingFlags.Public |
                                                  BindingFlags.IgnoreCase);

    ParameterExpression targetExp = Expression.Parameter(typeof(T), "target");
    ParameterExpression valueExp = Expression.Parameter(field.FieldType, "value");

    // Expression.Property can be used here as well
    MemberExpression fieldExp = Expression.Field(targetExp, field);
    BinaryExpression assignExp = Expression.Assign(fieldExp, valueExp);

    var setter = Expression.Lambda<Action<T, string>>(assignExp, targetExp, valueExp).Compile();

    setter(obj, "Hello World");

    //Console.WriteLine(obj.title);
}

私はこれをこのように呼びます:

var ii = new Controllers.SearchController.InstantItem();

SetValue<Controllers.SearchController.InstantItem>(ii);

問題はこの行です:

var setter = Expression.Lambda<Action<T, string>>(assignExp, targetExp, valueExp).Compile();

field.FieldTypeActionはジェネリックスを使用しているため、文字列を...に置き換えることはできません。

ステートメントを作成せずにこれを実行し、switch(field.FieldType)可能なタイプごとにジェネリックメソッドを配置する可能性はありますか?これは非常に時間がかかりますか?

4

2 に答える 2

1

たぶん、このようなもの

action = FormAction(fieldInfo);
action(obj,valueToSet);

もちろん、アクションを辞書にキャッシュする必要があります。

static Action<object, object> FormAction(FieldInfo fieldInfo)
{
    ParameterExpression obj = Expression.Parameter(typeof(object), fieldInfo.Name);
    ParameterExpression value = Expression.Parameter(typeof(object));

    MemberExpression fieldExp = Expression.Field(Expression.Convert(obj, fieldInfo.DeclaringType), fieldInfo.Name);
    BinaryExpression assignExp = Expression.Assign(fieldExp, Expression.Convert(value, fieldInfo.FieldType));

    return Expression.Lambda<Action<object, object>>(assignExp, obj, value).Compile();
}
于 2012-06-18T14:00:29.683 に答える
0

パラメーター ob 型オブジェクトを作成し、ラムダを内部的に正しいフィールド型にキャストします。

または、デリゲート型 (アクション) を実行時に動的に構築します。

または、次のように SetValue を定義することもできます。

SetValue<TObject, TProperty>

これにより、このメソッドはプロパティ タイプに対してジェネリックになります。

編集: オプション 1 が最適なようです。typeof(object)パラメータの型を次のように変更し、キャストを追加する必要があります。

valueExp = Expression.Convert(valueExp, field.FieldType)

Action<T, object>そして、デリゲート型として使用する必要があります。

于 2012-06-18T13:36:52.227 に答える