私はクラス内のすべてのフィールドに対して静的なリフレクションを実装しようとしています。 つまり、これらのすべてのフィールドの名前を使用してgetおよびsetを作成する必要があります。type.GetFields()の静的(式)の代替
は、私は今、私はこれらの2つの問題を持っているSet field value with Expression treeに答えを使用して、以下のソリューション
public class ExpressionSetterGetter
{
public class SetterGetter<T> where T : class
{
public Delegate getter;
public Action<T, object> setter;
}
public static Dictionary<string, SetterGetter<T>> GetFieldSetterGetterExpressions<T>() where T : class
{
var dic = new Dictionary<string, SetterGetter<T>>();
SetterGetter<T> setterGetter;
var type = typeof(T);
var fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
foreach (var fieldInfo in fields)
{
var targetExp = Expression.Parameter(type, "target");
var valueExp = Expression.Parameter(typeof(object), "value");
var fieldExp = Expression.Field(targetExp, fieldInfo);
var assignExp = Expression.Assign(fieldExp, Expression.Convert(valueExp, fieldExp.Type));
var fieldSetter = Expression.Lambda<Action<T, object>>(assignExp, targetExp, valueExp).Compile();
ParameterExpression objParm = Expression.Parameter(type, "obj");
MemberExpression fieldExpr = Expression.Field(objParm, fieldInfo.Name);
var fieldExprConverted = Expression.Convert(fieldExpr, typeof(object));
var fieldGetter = Expression.Lambda(fieldExprConverted, objParm).Compile();
setterGetter = new SetterGetter<T>() { setter = fieldSetter, getter = fieldGetter };
dic.Add(fieldInfo.Name, setterGetter);
}
return dic;
}
}
に来ました。
私はtype.GetFields()を使用しますが、MSDNには、それは反射法であると言います。 コンパイラが実行時の前に型を知らないことを意味します。 私はそうですか?正しい場合は、 式ツリーを使用する理由は何ですか。私が知っている限り、式ツリーはコンパイル時に コードに変換されますが、ほとんど追加コストがかかりません。
同じロジックです。どのようなラップする必要があるフィールドの名前を の名前のリストにパラメータとして配置する場合はどうなりますか。つまり、 の代わりにtype.GetFields()を使用すると、フィールドの名前をパラメータとして渡すだけです。
明らかpublic static Dictionary<string, SetterGetter<T>> GetFieldSetterGetterExpressions<T>(IEnumerable<string> fieldNames
)
、リストはコンパイル時に知られていないことができます。繰り返しますが、CLRはどのように反応しますか?
CLRは式ツリーが何であるかを知りません。それは誰でも書くことができる単なる図書館です。 – usr