各種Fwを自作してたりすると、Propertyに動的にアクセスするための手段がしばしば必要になります。
PropertyInfo.SetValue/GetValueでも実現できるのですが、実行速度がイマイチなのでDelegateを作成することをよくやります。
通常
Delegate.CreateDelegateを利用して、Propertyのgetter/setterをFunc/Actionとして取得します。
public static Func<TObj, TProp> GetGetter<TObj, TProp>(string propName)
=> (Func<TObj, TProp>)
Delegate.CreateDelegate(typeof(Func<TObj, TProp>),
typeof(TObj).GetProperty(propName).GetGetMethod());
public static Action<TObj, TProp> GetSetter<TObj, TProp>(string propName)
=> (Action<TObj, TProp>)
Delegate.CreateDelegate(typeof(Action<TObj, TProp>),
typeof(TObj).GetProperty(propName).GetSetMethod());
PCLの場合
PCLではDelegate.CreateDeleagteメソッドがないため、少しアクセス方法が変わります。
public static Func<TObj, TProp> GetGetter<TObj, TProp>(string propertyName)
=> (Func<TObj, TProp>)
typeof(TObj).GetTypeInfo().GetDeclaredProperty(propertyName).GetMethod
.CreateDelegate(typeof(Func<TObj, TProp>)));
public static Action<TObj, TProp> GetSetter<TObj, TProp>(string propertyName)
=> (Action<TObj, TProp>)
typeof(TObj).GetTypeInfo().GetDeclaredProperty(propertyName).SetMethod
.CreateDelegate(typeof(Action<TObj, TProp>)));
なお、作成したDelegateは適宜Cacheしておきましょう。
また、Propertyにはgetter/setterがない場合もあるので、目的によってはPropertyInfo.CanRead/CanWriteプロパティーを利用してアクセスできるかを確認するのも必要になるかもしれません。