Для свойств есть GetGetMethod
и GetSetMethod
, чтобы я мог:
Getter = (Func<S, T>)Delegate.CreateDelegate(typeof(Func<S, T>),
propertyInfo.GetGetMethod());
и
Setter = (Action<S, T>)Delegate.CreateDelegate(typeof(Action<S, T>),
propertyInfo.GetSetMethod());
Но как мне обойти FieldInfo
s?
Я не ищу делегатов для GetValue
и SetValue
(что означает, что я буду вызывать отражение каждый раз)
Getter = s => (T)fieldInfo.GetValue(s);
Setter = (s, t) => (T)fieldInfo.SetValue(s, t);
но если есть подход CreateDelegate
здесь? Я имею в виду поскольку присваивания возвращают значение, могу ли я обрабатывать назначения как метод? Если для этого существует дескриптор MethodInfo
? Другими словами, как передать правильный MethodInfo
параметр и получить значение из поля члена в метод CreateDelegate
, чтобы я получил делегат, с которым я могу напрямую читать и писать в поля?
Getter = (Func<S, T>)Delegate.CreateDelegate(typeof(Func<S, T>), fieldInfo.??);
Setter = (Action<S, T>)Delegate.CreateDelegate(typeof(Action<S, T>), fieldInfo.??);
Я могу построить выражение и скомпилировать его, но я ищу что-то более простое. В конце концов, я не возражаю против маршрута выражения, если нет ответа на заданный вопрос, как показано ниже:
var instExp = Expression.Parameter(typeof(S));
var fieldExp = Expression.Field(instExp, fieldInfo);
Getter = Expression.Lambda<Func<S, T>>(fieldExp, instExp).Compile();
if (!fieldInfo.IsInitOnly)
{
var valueExp = Expression.Parameter(typeof(T));
Setter = Expression.Lambda<Action<S, T>>(Expression.Assign(fieldExp, valueExp), instExp, valueExp).Compile();
}
Или я после несуществующего (так как я еще ничего не видел)?