private Action <object, object> CreateSetterDelegate(PropertyInfo propertyInfo)
        {
            if (!propertyInfo.CanWrite)
            {
                return(null);
            }

            var setMethod = propertyInfo.GetSetMethod(true);
            var dm        = new DynamicMethod("PropertySetter", null,
                                              new Type[] { typeof(object), typeof(object) }, propertyInfo.DeclaringType, true);

            var emiter = new EmitHelper(dm.GetILGenerator());

            emiter.Assert(!setMethod.IsStatic, e => e.ldarg_0.end())
            .ldarg_1
            .Assert(propertyInfo.PropertyType.IsValueType,
                    e => e.unbox_any(propertyInfo.PropertyType), e => e.castclass(propertyInfo.PropertyType))
            .Assert(!setMethod.IsStatic && !propertyInfo.DeclaringType.IsValueType,
                    e => e.callvirt(setMethod), e => e.call(setMethod))
            .ret();

            return((Action <object, object>)dm.CreateDelegate(typeof(Action <object, object>)));
        }
        private Func <object, object> CreateGetterDelegate(PropertyInfo propertyInfo)
        {
            if (!propertyInfo.CanRead)
            {
                return(null);
            }

            var getMethod = propertyInfo.GetGetMethod(true);

            var dm = new DynamicMethod("PropertyGetter", typeof(object),
                                       new Type[] { typeof(object) }, propertyInfo.DeclaringType, true);

            var emiter = new EmitHelper(dm.GetILGenerator());

            emiter.Assert(!getMethod.IsStatic, e => e.ldarg_0.end())
            .Assert(!getMethod.IsStatic && !propertyInfo.DeclaringType.IsValueType,
                    e => e.callvirt(getMethod), e => e.call(getMethod))
            .Assert(propertyInfo.PropertyType.IsValueType,
                    e => e.box(propertyInfo.PropertyType))
            .ret();

            return((Func <object, object>)dm.CreateDelegate(typeof(Func <object, object>)));
        }