I'm trying to implement static reflection for all fields in the class. In other words, I have to create get and set using name for all these fields.
I use the answers on Set field value with Expression tree, and came to the following solution
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;
}
}
Now, I have these two issues.
I use type.GetFields(), but MSDN says it is a reflection method. What means that the compiler doesn't know the type before runtime. Am I right? If it is correct, what is the reason to use the expression trees. As far as I know expression trees translate to the code at compile-time time, what means almost no additional costs.
The same logic. What if I put as a parameter a list with name of fields what have to be wrapped. In other words, instead of type.GetFields() I simply put the names of fields as parameters.
public static Dictionary<string, SetterGetter<T>> GetFieldSetterGetterExpressions<T>(IEnumerable<string> fieldNames
)
Obviously, the list can be not known at compile-time. Again, how the CLR will react?