mardi 16 août 2016

Static(expression) alternative for type.GetFields()

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 SetterGetter<T>  where T :class
        {
            public Func<object> 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();
            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();

             //   fieldExp = Expression.Convert(fieldExp, typeof(object));
                var fieldGetter  = Expression.Lambda<Func<object>>(fieldExp).Compile();

                setterGetter = new SetterGetter<T>() { setter = fieldSetter, getter = fieldGetter };

                dic.Add(fieldInfo.Name, setterGetter);
            }
            return dic;


        }

Now, I have these two issues.

  1. 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.

  2. 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?





Aucun commentaire:

Enregistrer un commentaire