Игнорируя, полезно ли это в ваших конкретных обстоятельствах (где я думаю, что выбранный вами подход работает отлично), ваш вопрос «есть ли способ преобразовать свойство в делегат».
Ну, может быть, что-то вроде.
Каждое свойство (за кулисами) состоит из одного или двух методов - метода set и / или метода get.И вы можете - если вы можете овладеть этими методами - создать делегаты, которые обертывают их.
Например, как только вы получите объект System.Reflection.PropertyInfo
, представляющий свойство типа TProp
вобъект типа TObj
, мы можем создать Action<TObj,TProp>
(то есть делегат, который принимает объект, для которого нужно установить свойство и значение, чтобы установить его), который оборачивает этот метод установки следующим образом:
Delegate.CreateDelegate(typeof (Action<TObj, TProp>), propertyInfo.GetSetMethod())
Или мы можем создать Action<TProp>
, который оборачивает установщик в конкретный экземпляр TObj
следующим образом:
Delegate.CreateDelegate(typeof (Action<TProp>), instance, propertyInfo.GetSetMethod())
Мы можем обернуть эту небольшую часть, используя статическое отражение метод расширения:
public static Action<T> GetPropertySetter<TObject, T>(this TObject instance, Expression<Func<TObject, T>> propAccessExpression)
{
var memberExpression = propAccessExpression.Body as MemberExpression;
if (memberExpression == null) throw new ArgumentException("Lambda must be a simple property access", "propAccessExpression");
var accessedMember = memberExpression.Member as PropertyInfo;
if (accessedMember == null) throw new ArgumentException("Lambda must be a simple property access", "propAccessExpression");
var setter = accessedMember.GetSetMethod();
return (Action<T>) Delegate.CreateDelegate(typeof(Action<T>), instance, setter);
}
и теперь я могу получить делегат 'setter' для свойства объекта, подобного этому:
MyClass myObject = new MyClass();
Action<string> setter = myObject.GetPropertySetter(o => o.Property1);
Это строго типизировано, в зависимости от типа самого свойства, поэтому оно устойчиво к рефакторингу и проверке типов во время компиляции.
Конечно, в вашем случае вы хотите иметь возможностьустановить свойство с помощью возможно нулевого объекта, поэтому строго типОбертка ed вокруг установщика - не единственное решение, но она дает вам кое-что, чтобы перейти к вашему SetPropertyFromDbValue
методу.