static Func<object, object> createGetterPropertyDelegate(Type type, PropertyInfo propertyInfo)
{
var getMethod = propertyInfo.GetGetMethod();
if (getMethod == null)
return null;
var getter = new DynamicMethod("_", typeof(object), new[] { typeof(object) }, type);
var il = getter.GetILGenerator();
if (!type.IsClass) // structs
{
var lv = il.DeclareLocal(type);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Unbox_Any, type);
il.Emit(OpCodes.Stloc_0);
il.Emit(OpCodes.Ldloca_S, lv);
il.EmitCall(OpCodes.Call, getMethod, null);
if (propertyInfo.PropertyType.IsValueType)
il.Emit(OpCodes.Box, propertyInfo.PropertyType);
}
else
{
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Castclass, propertyInfo.DeclaringType);
il.EmitCall(OpCodes.Callvirt, getMethod, null);
if (propertyInfo.PropertyType.IsValueType)
il.Emit(OpCodes.Box, propertyInfo.PropertyType);
}
il.Emit(OpCodes.Ret);
return (Func<object, object>)getter.CreateDelegate(typeof(Func<object, object>));
}