This is a theoretical question, I\'ve already got a solution to my problem that took me down a different path, but I think the question is still potentially interesting.
Ignoring whether this is useful in your specific circumstances (where I think the approach you've taken works just fine), your question is 'is there a way to convert a property into a delegate'.
Well, there kind of might be.
Every property actually (behind the scenes) consists of one or two methods - a set method and/or a get method. And you can - if you can get a hold of those methods - make delegates that wrap them.
For instance, once you've got hold of a System.Reflection.PropertyInfo
object representing a property of type TProp
on an object of type TObj
, we can create an Action
(that is, a delegate that takes an object on which to set the property and a value to set it to) that wraps that setter method as follows:
Delegate.CreateDelegate(typeof (Action), propertyInfo.GetSetMethod())
Or we can create an Action
that wraps the setter on a specific instance of TObj
like this:
Delegate.CreateDelegate(typeof (Action), instance, propertyInfo.GetSetMethod())
We can wrap that little lot up using a static reflection extension method:
public static Action GetPropertySetter(this TObject instance, Expression> 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) Delegate.CreateDelegate(typeof(Action), instance, setter);
}
and now I can get a hold of a 'setter' delegate for a property on an object like this:
MyClass myObject = new MyClass();
Action setter = myObject.GetPropertySetter(o => o.Property1);
That's strongly typed, based on the type of the property itself, so it's robust in the face of refactoring and compile-time typechecked.
Of course, in your case, you want to be able to set your property using a possibly-null object, so a strongly typed wrapper around the setter isn't the whole solution - but it does give you something to pass to your SetPropertyFromDbValue
method.