コード例 #1
0
        private static Action <TTarget, TValue> EmitFieldSetter <TTarget, TValue>(FieldInfo fieldInfo)
        {
            var dynamicMethod = EmitUtils.CreateDynamicMethod(
                "$Set" + fieldInfo.Name,
                null,
                new[] { typeof(TTarget), typeof(TValue) },
                fieldInfo.DeclaringType);
            var il = dynamicMethod.GetILGenerator();

            //copy the value to a local variable, unbox if needed
            il.DeclareLocal(fieldInfo.FieldType);
            il.Ldarg_1();
            if (!typeof(TValue).IsValueType)
            {
                il.CastValue(fieldInfo.FieldType);
            }
            il.Stloc_0();

            if (fieldInfo.IsStatic)
            {
                il.Ldloc_0();
                il.Stsfld(fieldInfo);
            }
            else
            {
                il.Ldarg_0();
                il.CastReference(fieldInfo.DeclaringType);
                il.Ldloc_0();
                il.Stfld(fieldInfo);
            }

            il.Ret();
            return((Action <TTarget, TValue>)dynamicMethod.CreateDelegate(typeof(Action <TTarget, TValue>)));
        }
コード例 #2
0
        private static Action <TTarget, TValue> EmitPropertySetter <TTarget, TValue>(
            PropertyInfo propertyInfo, MethodInfo setMethod)
        {
            var propType      = propertyInfo.PropertyType;
            var declaringType = propertyInfo.DeclaringType;
            var dynamicMethod = EmitUtils.CreateDynamicMethod(
                "$Set" + propertyInfo.Name,
                null,
                new[] { typeof(TTarget), typeof(TValue) },
                declaringType);
            var il = dynamicMethod.GetILGenerator();

            //copy the value to a local variable, unbox if needed
            il.DeclareLocal(propType);
            il.Ldarg_1();
            if (!typeof(TValue).IsValueType)
            {
                il.CastValue(propType);
            }
            il.Stloc_0();

            //push the instance, unbox if needed
            if (!setMethod.IsStatic)
            {
                il.Ldarg_0();
                il.CastReference(declaringType);
            }

            //push the value and call the method
            il.Ldloc_0();
            il.CallMethod(setMethod);
            il.Ret();

            return((Action <TTarget, TValue>)dynamicMethod.CreateDelegate(typeof(Action <TTarget, TValue>)));
        }
コード例 #3
0
        /// <summary>
        /// Creates a dynamic method for creating instances of the given type.
        /// The given type must have a public parameterless constructor.
        /// </summary>
        /// <param name="type">The type of the instances to be created.</param>
        /// <returns>
        /// A dynamic method for creating instances of the given type.
        /// </returns>
        /// <exception cref="ArgumentNullException"><paramref name="type"/> is null.</exception>
        /// <exception cref="ArgumentException">
        /// The given type is an interface, or is abstract,
        /// or does not have a public parameterless constructor.
        /// </exception>
        public static Func <object> CreateDelegate(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            if (type.IsInterface)
            {
                throw new ArgumentException(string.Format("{0} is an interface.", type), "type");
            }

            if (type.IsAbstract)
            {
                throw new ArgumentException(string.Format("{0} is abstract.", type), "type");
            }

            ConstructorInfo constructorInfo = null;

            if (type.IsClass)
            {
                constructorInfo = type.GetConstructor(Type.EmptyTypes);

                if (constructorInfo == null)
                {
                    throw new ArgumentException(
                              string.Format("{0} does not have a public parameterless constructor.", type), "type");
                }
            }

            var dynamicMethod = EmitUtils.CreateDynamicMethod(
                "$Create" + type, typeof(object), Type.EmptyTypes, type);
            var il = dynamicMethod.GetILGenerator();

            if (type.IsClass)
            {
                il.Newobj(constructorInfo);
            }
            else //value type
            {
                il.DeclareLocal(type);
                il.LoadLocalVariableAddress(0);
                il.Initobj(type);

                il.LoadLocalVariable(0);
                il.Box(type);
            }

            il.Ret();
            return((Func <object>)dynamicMethod.CreateDelegate(typeof(Func <object>)));
        }
コード例 #4
0
        private static Func <TSource, TReturn> EmitFieldGetter <TSource, TReturn>(FieldInfo fieldInfo)
        {
            var dynamicMethod = EmitUtils.CreateDynamicMethod(
                "$Get" + fieldInfo.Name,
                typeof(TReturn),
                new[] { typeof(TSource) },
                fieldInfo.DeclaringType);
            var il = dynamicMethod.GetILGenerator();

            if (fieldInfo.IsStatic)
            {
                il.Ldsfld(fieldInfo);
            }
            else
            {
                //unbox the source if needed
                if (typeof(TSource).IsValueType)
                {
                    il.Ldarga_S(0);
                }
                else
                {
                    il.Ldarg_0();
                    il.CastReference(fieldInfo.DeclaringType);
                }

                il.Ldfld(fieldInfo);
            }

            //box the return value if needed
            if (!typeof(TReturn).IsValueType && fieldInfo.FieldType.IsValueType)
            {
                il.Box(fieldInfo.FieldType);
            }
            il.Ret();

            return((Func <TSource, TReturn>)dynamicMethod.CreateDelegate(typeof(Func <TSource, TReturn>)));
        }
コード例 #5
0
        private static Func <TSource, TReturn> EmitPropertyGetter <TSource, TReturn>(
            PropertyInfo propertyInfo, MethodInfo getMethod)
        {
            var dynamicMethod = EmitUtils.CreateDynamicMethod(
                "$Get" + propertyInfo.Name,
                typeof(TReturn),
                new[] { typeof(TSource) },
                propertyInfo.DeclaringType);
            var il = dynamicMethod.GetILGenerator();

            if (!getMethod.IsStatic)
            {
                //unbox the input value if needed
                if (typeof(TSource).IsValueType)
                {
                    il.Ldarga_S(0);
                }
                else
                {
                    il.Ldarg_0();
                    il.CastReference(propertyInfo.DeclaringType);
                }
            }

            il.CallMethod(getMethod);

            //box the return value if needed
            if (!typeof(TReturn).IsValueType && propertyInfo.PropertyType.IsValueType)
            {
                il.Box(propertyInfo.PropertyType);
            }

            il.Ret();

            return((Func <TSource, TReturn>)dynamicMethod.CreateDelegate(typeof(Func <TSource, TReturn>)));
        }
コード例 #6
0
        /// <summary>
        /// Creates a dynamic method for invoking the method from the given <see cref="MethodInfo"/>
        /// and indicates whether to perform a arguments validation in the dynamic method.
        /// </summary>
        /// <param name="methodInfo">
        /// The instance of <see cref="MemberInfo"/> from which the dyanmic method is to be created.
        /// </param>
        /// <param name="validateArguments">
        /// If <c>true</c>, the dynamic method will validate if the instance or the array of arguments
        /// is null and check the length of the array to avoid the exceptions such as
        /// <see cref="NullReferenceException"/> or <see cref="IndexOutOfRangeException"/>,
        /// an <see cref="ArgumentNullException"/> or <see cref="ArgumentException"/> will be thrown instead.
        /// </param>
        /// <returns>
        /// The delegate has two parameters: the first for the object instance (will be ignored
        /// if the method is static), and the second for the arguments of the method (will be
        /// ignored if the method has no arguments)/
        /// The return value of the delegate will be <c>null</c> if the method has no return value.
        /// </returns>
        /// <exception cref="ArgumentNullException"><paramref name="methodInfo"/> is null.</exception>
        public static Func <object, object[], object> CreateDelegate(
            MethodInfo methodInfo, bool validateArguments)
        {
            if (methodInfo == null)
            {
                throw new ArgumentNullException("methodInfo");
            }

            var args          = methodInfo.GetParameters();
            var dynamicMethod = EmitUtils.CreateDynamicMethod(
                "$Call" + methodInfo.Name,
                typeof(object),
                new[] { typeof(object), typeof(object[]) },
                methodInfo.DeclaringType);
            var il = dynamicMethod.GetILGenerator();

            var lableValidationCompleted = il.DefineLabel();

            if (!validateArguments || (methodInfo.IsStatic && args.Length == 0))
            {
                il.Br_S(lableValidationCompleted); //does not need validation
            }
            else
            {
                var lableCheckArgumentsRef    = il.DefineLabel();
                var lableCheckArgumentsLength = il.DefineLabel();

                //check if the instance is null
                if (!methodInfo.IsStatic)
                {
                    // if (instance == null) throw new ArgumentNullExcpeiton("instance");
                    il.Ldarg_0();
                    il.Brtrue_S(args.Length > 0 ? lableCheckArgumentsRef : lableValidationCompleted);

                    il.ThrowArgumentsNullExcpetion("instance");
                }

                //check the arguments
                if (args.Length > 0)
                {
                    // if (arguments == null) throw new ArgumentNullExcpeiton("arguments");
                    il.MarkLabel(lableCheckArgumentsRef);
                    il.Ldarg_1();
                    il.Brtrue_S(lableCheckArgumentsLength);

                    il.ThrowArgumentsNullExcpetion("arguments");

                    // if (arguments.Length < $(args.Length)) throw new ArgumentExcpeiton(msg, "arguments");
                    il.MarkLabel(lableCheckArgumentsLength);
                    il.Ldarg_1();
                    il.Ldlen();
                    il.Conv_I4();
                    il.LoadInt32(args.Length);
                    il.Bge_S(lableValidationCompleted);

                    il.ThrowArgumentsExcpetion("Not enough arguments in the argument array.", "arguments");
                }
            }

            il.MarkLabel(lableValidationCompleted);
            if (!methodInfo.IsStatic)
            {
                il.Ldarg_0();
                il.CastReference(methodInfo.DeclaringType);
            }

            if (args.Length > 0)
            {
                for (int i = 0; i < args.Length; i++)
                {
                    il.Ldarg_1();
                    il.LoadInt32((short)i);
                    il.Ldelem_Ref();
                    il.CastValue(args[i].ParameterType);
                }
            }

            il.CallMethod(methodInfo);
            if (methodInfo.ReturnType == typeof(void))
            {
                il.Ldc_I4_0(); //return null
            }
            else
            {
                il.BoxIfNeeded(methodInfo.ReturnType);
            }
            il.Ret();

            var methodDelegate = dynamicMethod.CreateDelegate(typeof(Func <object, object[], object>));

            return((Func <object, object[], object>)methodDelegate);
        }
コード例 #7
0
        /// <summary>
        /// Creates a dynamic method for creating instances from the given <see cref="ConstructorInfo"/>
        /// and indicates whether to perform a arguments validation in the dynamic method.
        /// </summary>
        /// <param name="constructorInfo">The constructor from which instances will be created.</param>
        /// <param name="validateArguments">
        /// If <c>true</c>, the dynamic method will validate if the array of arguments is null
        /// and check the length of the array to avoid the exceptions such as
        /// <see cref="NullReferenceException"/> or <see cref="IndexOutOfRangeException"/>,
        /// an <see cref="ArgumentNullException"/> or <see cref="ArgumentException"/> will be thrown instead.
        /// </param>
        /// <returns>
        /// A dynamic method for creating instances from the given constructor, the method receives an
        /// array as the arguments of the constructor.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="constructorInfo"/> is null.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// The declaring type of the construcor is abstract.
        /// </exception>
        public static Func <object[], object> CreateDelegate(ConstructorInfo constructorInfo, bool validateArguments)
        {
            if (constructorInfo == null)
            {
                throw new ArgumentNullException("constructorInfo");
            }

            var delclaringType = constructorInfo.DeclaringType;

            if (delclaringType.IsAbstract)
            {
                throw new ArgumentException(
                          "The declaring type of the constructor is abstract.", "constructorInfo");
            }

            var dynamicMethod = EmitUtils.CreateDynamicMethod(
                "$Create" + delclaringType.Name,
                typeof(object),
                new[] { typeof(object[]) },
                constructorInfo.DeclaringType);
            var il = dynamicMethod.GetILGenerator();

            var args = constructorInfo.GetParameters();
            var lableValidationCompleted = il.DefineLabel();

            if (!validateArguments || args.Length == 0)
            {
                il.Br_S(lableValidationCompleted);
            }
            else
            {
                var lableCheckArgumentsLength = il.DefineLabel();

                // if (arguments == null) throw new ArgumentNullExcpeiton("arguments");
                il.Ldarg_0();
                il.Brtrue_S(lableCheckArgumentsLength);

                il.ThrowArgumentsNullExcpetion("arguments");

                // if (arguments.Length < $(args.Length)) throw new ArgumentExcpeiton(msg, "arguments");
                il.MarkLabel(lableCheckArgumentsLength);
                il.Ldarg_0();
                il.Ldlen();
                il.Conv_I4();
                il.LoadInt32(args.Length);
                il.Bge_S(lableValidationCompleted);

                il.ThrowArgumentsExcpetion("Not enough arguments in the argument array.", "arguments");
            }

            il.MarkLabel(lableValidationCompleted);
            if (args.Length > 0)
            {
                for (int i = 0; i < args.Length; i++)
                {
                    il.Ldarg_0();
                    il.LoadInt32((short)i);
                    il.Ldelem_Ref();
                    il.CastValue(args[i].ParameterType);
                }
            }
            il.Newobj(constructorInfo);
            il.Ret();

            return((Func <object[], object>)dynamicMethod.CreateDelegate(typeof(Func <object[], object>)));
        }