Exemplo n.º 1
0
        /* 修改字段
         * IL:
         * void Action(TInstance instance, TField value) {
         * 1. 载入第一参数:
         *    ldarg.0
         * 2. 转换实例类型: (如果需要)
         *
         *
         * 3. 载入第二参数:
         *    ldarg.1
         * 4. 转换字段类型: (如果需要)
         *
         *
         * 5. 修改字段:
         *    {OpCode} {FieldTypeName} {TargetTypeName::FieldName}
         *    {OpCode}:
         *      1). 实例: stfld;
         *      2). 静态: stsfld;
         *    {FieldTypeName}:
         *      1). 标量类型: "{TypeName}";
         *      2). 引用类型: "class {TypeName}";
         *      3). 数值类型: "valuetype {TypeName}";
         *
         * 6. 退出方法
         *    ret
         * }
         */
        Delegate InternalFieldSetWithDynamic(FieldInfo member, Type instance, Type value)
        {
            var field = member.FieldType;

            if (value == null)
            {
                value = field;
            }

            if (!member.IsStatic)
            {
                var reflected = member.ReflectedType;
                if (instance == null)
                {
                    instance = reflected;
                }

                var @dynamic = CreateDynamicMethod(null, new[] { instance, value }, _DynamicOptionsField, member);
                var il       = @dynamic.GetILGenerator();

                il.Emit(OpCodes.Ldarg_0);
                ConvertIfNeeded(il, reflected, instance); //

                il.Emit(OpCodes.Ldarg_1);
                ConvertIfNeeded(il, field, value); //

                il.Emit(OpCodes.Stfld, member);

                il.Emit(OpCodes.Ret);

                return(@dynamic.CreateDelegate(TypeMemberSetInstance.MakeGenericType(new[] { instance, value })));
            }
            else
            {
                if (instance != null)
                {
                    throw new ArgumentException();
                }

                var @dynamic = CreateDynamicMethod(null, new[] { value }, _DynamicOptionsField, member);
                var il       = @dynamic.GetILGenerator();

                il.Emit(OpCodes.Ldarg_0);
                ConvertIfNeeded(il, field, value); //

                il.Emit(OpCodes.Stsfld, member);

                il.Emit(OpCodes.Ret);

                return(@dynamic.CreateDelegate(TypeMemberSetStatic.MakeGenericType(new[] { value })));
            }
        }
Exemplo n.º 2
0
        /* 修改属性
         * // IL代码: 实际访问 set_PropertyName() 方法;
         *
         * 1. 载入第一参数:
         *    ldarg.0
         * 2. 转换实例类型: (如果需要)
         *
         *
         * 3. 载入第二参数:
         *    ldarg.1
         * 4. 转换字段类型: (如果需要)
         *
         *
         * 5. 修改字段:
         *    {OpCode} void {TargetTypeName}::set_PropertyName({PropertyTypeName})
         *    {OpCode}:
         *      1). 实例: callvirt instance;
         *      2). 静态: call;
         *    {PropertyTypeName}:
         *      1). 标量类型: "{TypeName}";
         *      2). 引用类型: "class {TypeName}";
         *      3). 数值类型: "valuetype {TypeName}";
         *
         * 6. 退出方法
         *    ret
         */
        Delegate InternalPropertySetWithDynamic(PropertyInfo member, Type instance, Type value)
        {
            var method = member.GetSetMethod(true);

            var property = member.PropertyType;

            if (value == null)
            {
                value = property;
            }

            if (!method.IsStatic)
            {
                var reflected = method.ReflectedType;
                if (instance == null)
                {
                    instance = reflected;
                }

                var @dynamic = CreateDynamicMethod(null, new[] { instance, value }, _DynamicOptionsProperty, member);
                var il       = @dynamic.GetILGenerator();

                il.Emit(OpCodes.Ldarg_0);
                ConvertIfNeeded(il, reflected, instance); //

                il.Emit(OpCodes.Ldarg_1);
                ConvertIfNeeded(il, property, value); //

                if (reflected.IsValueType)
                {
                    il.EmitCall(OpCodes.Call, method, null);
                }
                else
                {
                    il.EmitCall(OpCodes.Callvirt, method, null);
                }

                il.Emit(OpCodes.Ret);

                return(@dynamic.CreateDelegate(TypeMemberSetInstance.MakeGenericType(new[] { instance, value })));
            }
            else
            {
                if (instance != null)
                {
                    throw Error.StaticObjectCannotConvertType("instance");
                }

                var @dynamic = CreateDynamicMethod(null, new[] { value }, _DynamicOptionsProperty, member);
                var il       = @dynamic.GetILGenerator();

                il.Emit(OpCodes.Ldarg_0);
                ConvertIfNeeded(il, property, value); //

                il.EmitCall(OpCodes.Call, method, null);

                il.Emit(OpCodes.Ret);

                return(@dynamic.CreateDelegate(TypeMemberSetStatic.MakeGenericType(new[] { value })));
            }
        }