예제 #1
0
        public void TestNotThrowsExceptionOnNull()
        {
            string methodName = null;

            methodName = _generator.GetString(false, false, true, MinStringLength, MaxStringLength);
            Type returnType = typeof(void);

            TypeBuilder   typeBuilder = GetTestTypeBuilder();
            MethodBuilder builder     = typeBuilder.DefineMethod(methodName,
                                                                 TestMethodAttributes);

            Type[] typeParameters =
                builder.DefineGenericParameters(new string[] { "T" }).Select(a => a.AsType()).ToArray();
            builder.SetParameters(typeParameters);
            builder.SetReturnType(returnType);

            MethodInfo methodInfo = builder.MakeGenericMethod(null);
        }
        public void TestForEqualObjects2()
        {
            string methodName = null;

            methodName = _generator.GetString(false, false, true, MinStringLength, MaxStringLength);
            TypeBuilder   typeBuilder = GetTestTypeBuilder();
            MethodBuilder builder1    = typeBuilder.DefineMethod(methodName,
                                                                 MethodAttributes.Public);

            string[] typeParamNames = { "T", "U" };
            GenericTypeParameterBuilder[] Parameters = builder1.DefineGenericParameters(typeParamNames);
            MethodBuilder builder2 = typeBuilder.DefineMethod(methodName,
                                                              MethodAttributes.Public);

            Parameters = builder2.DefineGenericParameters(typeParamNames);

            Assert.Equal(builder1.GetHashCode(), builder2.GetHashCode());
        }
예제 #3
0
        public void TestGenericMethodWithReturnTypeRequiredModifiersSet()
        {
            string methodName = null;

            methodName = TestLibrary.Generator.GetString(false, false, true, MinStringLength, MaxStringLength);
            TypeBuilder   typeBuilder = GetTestTypeBuilder();
            MethodBuilder builder     = typeBuilder.DefineMethod(methodName,
                                                                 TestMethodAttributes);

            string[] typeParamNames = { "T" };
            GenericTypeParameterBuilder[] typeParameters =
                builder.DefineGenericParameters(typeParamNames);
            GenericTypeParameterBuilder desiredReturnType = typeParameters[0];

            builder.SetSignature(desiredReturnType.AsType(), null, null, null, null, null);

            VerifyMethodSignature(typeBuilder, builder, desiredReturnType.AsType());
        }
        public void DefineGenericParameters_TwoTypeParameters(string[] names)
        {
            TypeBuilder   type   = Helpers.DynamicType(TypeAttributes.NotPublic);
            MethodBuilder method = type.DefineMethod("TestMethod", MethodAttributes.Public);

            GenericTypeParameterBuilder[] parameters = method.DefineGenericParameters(names);
            Assert.True(method.IsGenericMethod);
            Assert.True(method.IsGenericMethodDefinition);
            Assert.Equal(names.Length, parameters.Length);

            for (int i = 0; i < names.Length; i++)
            {
                GenericTypeParameterBuilder parameter = parameters[i];
                Assert.Equal(method, parameter.DeclaringMethod);
                Assert.Equal(names[i], parameters[i].Name);
                Assert.Equal(i, parameters[i].GenericParameterPosition);
            }
        }
예제 #5
0
        /// <summary>
        /// Defines the generic method parameters based on the specified method.
        /// </summary>
        /// <param name="methodBuilder">The method builder.</param>
        /// <param name="methodBase">The method base.</param>
        /// <returns>The generic parameter types.</returns>
        /// <remarks>
        /// Custom attributes are not considered by this method.
        /// </remarks>
        public static Type[] DefineGenericParameters(this MethodBuilder methodBuilder, MethodBase methodBase)
        {
            if (methodBuilder == null)
            {
                throw new ArgumentNullException("methodBuilder");
            }

            if (methodBase == null)
            {
                throw new ArgumentNullException("methodBase");
            }

            if (!methodBase.IsGenericMethodDefinition)
            {
                return(Type.EmptyTypes);
            }

            var genericParameterTypes    = methodBase.GetGenericArguments();
            var genericParameterNames    = Array.ConvertAll(genericParameterTypes, t => t.Name);
            var genericParameterBuilders = methodBuilder.DefineGenericParameters(genericParameterNames);

            foreach (var genericParameterBuilder in genericParameterBuilders)
            {
                var genericParameterType = genericParameterTypes[genericParameterBuilder.GenericParameterPosition];

                // Set generic parameter attributes.
                genericParameterBuilder.SetGenericParameterAttributes(genericParameterType.GenericParameterAttributes);

                // Set generic parameter constraints.
                var genericParameterConstraints = genericParameterType.GetGenericParameterConstraints();
                var baseTypeConstraint          = genericParameterConstraints.FirstOrDefault(t => t.IsClass);

                if (baseTypeConstraint != null)
                {
                    genericParameterBuilder.SetBaseTypeConstraint(baseTypeConstraint);
                }

                var interfaceConstraints = genericParameterConstraints.Where(t => t.IsInterface).ToArray();

                genericParameterBuilder.SetInterfaceConstraints(interfaceConstraints);
            }

            return(Array.ConvertAll(genericParameterBuilders, b => (Type)b));
        }
        private Dictionary <Type, Type> DefineMethodGenericParameters(MethodBuilder methodBuilder, MethodInfo methodInfo)
        {
            var genericParameters     = methodInfo.GetGenericArguments();
            var genericParameterNames = Enumerable.Range(1, genericParameters.Length).Select(it => $"T{it}").ToArray();
            var builders = methodBuilder.DefineGenericParameters(genericParameterNames);

            for (int index = 0; index < genericParameters.Length; index++)
            {
                var builder          = builders[index];
                var genericParameter = genericParameters[index];
                if (!genericParameter.IsGenericParameter)
                {
                    continue;
                }
                builder.SetGenericParameterAttributes(genericParameter.GenericParameterAttributes);

                var interfaceConstraints = new List <Type>();
                foreach (Type constraint in genericParameter.GetGenericParameterConstraints())
                {
                    if (constraint.IsClass)
                    {
                        builder.SetBaseTypeConstraint(constraint);
                    }
                    else
                    {
                        interfaceConstraints.Add(constraint);
                    }
                }
                if (interfaceConstraints.Count > 0)
                {
                    builder.SetInterfaceConstraints(interfaceConstraints.ToArray());
                }
            }

            var map = new Dictionary <Type, Type>();
            var genericParameters2 = methodBuilder.GetGenericArguments();

            for (int index = 0; index < genericParameters.Length; index++)
            {
                map.Add(genericParameters[index], genericParameters2[index]);
            }

            return(map);
        }
        private static MethodBuilder GenerateMethodSignature(string name, MethodInfo method, TypeBuilder typeBuilder)
        {
            const MethodAttributes methodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig |
                                                      MethodAttributes.Virtual;

            ParameterInfo[] parameters = method.GetParameters();

            MethodBuilder methodBuilder = typeBuilder.DefineMethod(name,
                                                                   methodAttributes,
                                                                   CallingConventions.HasThis,
                                                                   method.ReturnType,
                                                                   parameters.Select(param => param.ParameterType).ToArray());

            System.Type[] typeArgs = method.GetGenericArguments();

            if (typeArgs.Length > 0)
            {
                var typeNames = new List <string>();

                for (int index = 0; index < typeArgs.Length; index++)
                {
                    typeNames.Add(string.Format("T{0}", index));
                }

                var typeArgsBuilder = methodBuilder.DefineGenericParameters(typeNames.ToArray());

                for (int index = 0; index < typeArgs.Length; index++)
                {
                    // Copy generic parameter attributes (Covariant, Contravariant, ReferenceTypeConstraint,
                    // NotNullableValueTypeConstraint, DefaultConstructorConstraint).
                    typeArgsBuilder[index].SetGenericParameterAttributes(typeArgs[index].GenericParameterAttributes);

                    // Copy generic parameter constraints (class and interfaces).
                    var typeConstraints = typeArgs[index].GetGenericParameterConstraints();

                    var baseTypeConstraint = typeConstraints.SingleOrDefault(x => x.IsClass);
                    typeArgsBuilder[index].SetBaseTypeConstraint(baseTypeConstraint);

                    var interfaceTypeConstraints = typeConstraints.Where(x => !x.IsClass).ToArray();
                    typeArgsBuilder[index].SetInterfaceConstraints(interfaceTypeConstraints);
                }
            }
            return(methodBuilder);
        }
예제 #8
0
        public void TestWithGenericReturnType()
        {
            string methodName = null;

            methodName = _generator.GetString(false, false, true, MinStringLength, MaxStringLength);

            TypeBuilder   typeBuilder = GetTestTypeBuilder();
            MethodBuilder builder     = typeBuilder.DefineMethod(
                methodName,
                MethodAttributes.Public);

            string[] typeParamNames = { "T", "U" };
            GenericTypeParameterBuilder[] desiredParameters = builder.DefineGenericParameters(typeParamNames);

            builder.SetReturnType(desiredParameters[0].AsType());

            Type[] actualParameters = builder.GetGenericArguments();
            VerificationHelper(desiredParameters, actualParameters);
        }
        public void TestThrowsExceptionForEmptyArray()
        {
            string       name    = "Assembly1";
            AssemblyName asmname = new AssemblyName();

            asmname.Name = name;

            AssemblyBuilder asmbuild  = AssemblyBuilder.DefineDynamicAssembly(asmname, AssemblyBuilderAccess.Run);
            ModuleBuilder   modbuild  = TestLibrary.Utilities.GetModuleBuilder(asmbuild, "Module1");
            TypeBuilder     tpbuild   = modbuild.DefineType("C1", TypeAttributes.Public);
            MethodBuilder   methbuild = tpbuild.DefineMethod("method1", MethodAttributes.Public | MethodAttributes.Static);


            string[] typeParamNames = { };
            Assert.Throws <ArgumentException>(() =>
            {
                GenericTypeParameterBuilder[] typeParameters = methbuild.DefineGenericParameters(typeParamNames);
            });
        }
예제 #10
0
        public void Bug354757()
        {
            TypeBuilder gtb = module.DefineType(genTypeName(), TypeAttributes.Public);

            gtb.DefineGenericParameters("T");
            MethodBuilder mb = gtb.DefineMethod("foo", MethodAttributes.Public);

            mb.DefineGenericParameters("S");
            Assert.IsTrue(mb.IsGenericMethodDefinition);

            Type       gt = gtb.MakeGenericType(typeof(object));
            MethodInfo m  = TypeBuilder.GetMethod(gt, mb);

            Assert.IsTrue(m.IsGenericMethodDefinition);

            MethodInfo mopen = m.MakeGenericMethod(m.GetGenericArguments());

            Assert.IsFalse(mopen.IsGenericMethodDefinition);
        }
예제 #11
0
        public void DefineGenericParameter_MultipleParameters()
        {
            TypeBuilder   type   = Helpers.DynamicType(TypeAttributes.Public);
            MethodBuilder method = type.DefineMethod("TestMethod", MethodAttributes.Public, typeof(int), new Type[0]);

            method.DefineGenericParameters(new string[] { "T", "U", "V" });

            ILGenerator ilGenerator = method.GetILGenerator();

            ilGenerator.Emit(OpCodes.Ldc_I4, 100);
            ilGenerator.Emit(OpCodes.Ret);

            Type resultType = type.CreateType();

            Type[]     typeArguments     = { typeof(int), typeof(string), typeof(object) };
            MethodInfo constructedMethod = resultType.GetMethod("TestMethod").MakeGenericMethod(typeArguments);

            Assert.Equal(typeArguments, constructedMethod.GetGenericArguments());
        }
예제 #12
0
        public void TestWithMultipleGenericParameters()
        {
            var methodName = _generator.GetString(false, false, true, MinStringLength, MaxStringLength);

            TypeBuilder   typeBuilder = GetTestTypeBuilder();
            MethodBuilder builder     = typeBuilder.DefineMethod(methodName,
                                                                 TestMethodAttributes);

            string[] typeParamNames = { "T", "U" };
            GenericTypeParameterBuilder[] typeParameters =
                builder.DefineGenericParameters(typeParamNames);
            Type desiredReturnType = typeParameters[1].AsType();

            builder.SetReturnType(desiredReturnType);

            typeBuilder.CreateTypeInfo().AsType();

            VerifyReturnType(builder, desiredReturnType);
        }
예제 #13
0
        public void SetSignature_NullReturnType_RequiredCustomModifiers_OptionalCustomModifiers()
        {
            TypeBuilder   type   = Helpers.DynamicType(TypeAttributes.Abstract);
            MethodBuilder method = type.DefineMethod("TestMethod", MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual);

            GenericTypeParameterBuilder[] typeParameters    = method.DefineGenericParameters("T");
            GenericTypeParameterBuilder   desiredReturnType = typeParameters[0];

            Type[]   desiredParamType = new Type[] { typeof(void) };
            Type[][] parameterTypeRequiredCustomModifiers = new Type[desiredParamType.Length][];
            Type[][] parameterTypeOptionalCustomModifiers = new Type[desiredParamType.Length][];
            for (int i = 0; i < desiredParamType.Length; ++i)
            {
                parameterTypeRequiredCustomModifiers[i] = null;
                parameterTypeOptionalCustomModifiers[i] = null;
            }

            method.SetSignature(desiredReturnType.AsType(), null, null, desiredParamType, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers);
        }
예제 #14
0
        public void PosTest5()
        {
            ModuleBuilder module = Helpers.DynamicModule();

            TypeBuilder type1 = module.DefineType("C1", TypeAttributes.Public);

            type1.DefineGenericParameters("T");

            MethodBuilder method1 = type1.DefineMethod("meth1", MethodAttributes.Public, typeof(int), new Type[0]);

            method1.DefineGenericParameters("U");

            int expectedRet = 1;
            // Generate code for the method that we are going to use as MethodInfo in ILGenerator.Emit()
            ILGenerator ilGenerator1 = method1.GetILGenerator();

            ilGenerator1.Emit(OpCodes.Ldc_I4, expectedRet);
            ilGenerator1.Emit(OpCodes.Ret);

            // create the type where this method is in
            Type       createdType1   = type1.CreateTypeInfo().AsType();
            Type       genericType    = createdType1.MakeGenericType(typeof(int));
            MethodInfo createdMethod1 = genericType.GetMethod("meth1");
            MethodInfo genericMethod  = createdMethod1.MakeGenericMethod(typeof(string));

            TypeBuilder   type2   = module.DefineType("C2", TypeAttributes.Public);
            MethodBuilder method2 = type2.DefineMethod("meth2", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new Type[0]);

            // Generate code for the method which will be invoking the first method
            ILGenerator ilGenerator2 = method2.GetILGenerator();

            ilGenerator2.Emit(OpCodes.Newobj, genericType.GetConstructor(new Type[0]));
            ilGenerator2.Emit(OpCodes.Callvirt, genericMethod);
            ilGenerator2.Emit(OpCodes.Ret);

            // Create the type whose method will be invoking the MethodInfo method
            Type       createdType2   = type2.CreateTypeInfo().AsType();
            MethodInfo createdMethod2 = createdType2.GetMethod("meth2");

            // meth2 should invoke meth1 which should return value 'methodRet'
            Assert.Equal(expectedRet, createdMethod2.Invoke(null, null));
        }
예제 #15
0
        public void SetSignature_NullOnReturnType_CustomModifiersSetCorrectly()
        {
            int           arraySize = 10;
            TypeBuilder   type      = Helpers.DynamicType(TypeAttributes.Abstract);
            MethodBuilder method    = type.DefineMethod("TestMethod", MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual);

            GenericTypeParameterBuilder[] typeParameters    = method.DefineGenericParameters("T");
            GenericTypeParameterBuilder   desiredReturnType = typeParameters[0];

            Type[]   desiredParamType = null;
            Type[][] parameterTypeRequiredCustomModifiers = new Type[arraySize][];
            Type[][] parameterTypeOptionalCustomModifiers = new Type[arraySize][];
            for (int i = 0; i < arraySize; ++i)
            {
                parameterTypeRequiredCustomModifiers[i] = null;
                parameterTypeOptionalCustomModifiers[i] = null;
            }

            method.SetSignature(desiredReturnType.AsType(), null, null, desiredParamType, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers);
        }
예제 #16
0
        /// <summary>
        /// DefineDerivedMethodSignature 定义动态类中方法的签名,支持泛型方法。
        /// </summary>
        public static MethodBuilder DefineDerivedMethodSignature(TypeBuilder typeBuilder, MethodInfo baseMethod)
        {
            Type[]        argTypes      = EmitHelper.GetParametersType(baseMethod);
            MethodBuilder methodBuilder = typeBuilder.DefineMethod(baseMethod.Name, baseMethod.Attributes & ~MethodAttributes.Abstract, baseMethod.ReturnType, argTypes);

            #region GenericMethod
            if (baseMethod.IsGenericMethod)
            {
                Type[]   genericParaTypes = baseMethod.GetGenericArguments();
                string[] genericParaNames = EmitHelper.GetGenericParameterNames(baseMethod);
                GenericTypeParameterBuilder[] genericTypeParameterBuilders = methodBuilder.DefineGenericParameters(genericParaNames);
                for (int i = 0; i < genericTypeParameterBuilders.Length; i++)
                {
                    genericTypeParameterBuilders[i].SetInterfaceConstraints(genericParaTypes[i].GetGenericParameterConstraints());
                }
            }
            #endregion

            return(methodBuilder);
        }
예제 #17
0
        public void ILGen_GenericTypeParameterBuilder()
        {
            TypeBuilder   tb = module.DefineType(genTypeName(), TypeAttributes.Public);
            MethodBuilder mb = tb.DefineMethod("box_int",
                                               MethodAttributes.Public | MethodAttributes.Static, typeof(object), new Type [] { typeof(int) });

            GenericTypeParameterBuilder[] pars = mb.DefineGenericParameters(new string [] { "foo" });

            ILGenerator ilgen = mb.GetILGenerator();

            ilgen.Emit(OpCodes.Ldarg_0);
            ilgen.Emit(OpCodes.Box, pars [0]);
            ilgen.Emit(OpCodes.Ret);

            Type       t   = tb.CreateType();
            MethodInfo mi  = t.GetMethod("box_int");
            MethodInfo mi2 = mi.MakeGenericMethod(new Type [] { typeof(int) });

            Assert.AreEqual(1, mi2.Invoke(null, new object [] { 1 }));
        }
예제 #18
0
        private void SetupGenericParameters(MethodBuilder methodBuilder)
        {
            if (methodToOverride.IsGenericMethod)
            {
                Type[]   genericArguments = methodToOverride.GetGenericArguments();
                string[] names            = Seq.Make(genericArguments)
                                            .Map <string>(delegate(Type t) { return(t.Name); })
                                            .ToArray();
                GenericTypeParameterBuilder[] builders = methodBuilder.DefineGenericParameters(names);
                for (int i = 0; i < genericArguments.Length; ++i)
                {
                    builders[i].SetGenericParameterAttributes(genericArguments[i].GenericParameterAttributes);

                    foreach (Type type in genericArguments[i].GetGenericParameterConstraints())
                    {
                        builders[i].SetBaseTypeConstraint(type);
                    }
                }
            }
        }
예제 #19
0
            protected internal override void GeneratingGenericParameter(MethodBuilder declaringMethod)
            {
                var genericArguments         = method.GetGenericArguments().ToArray();
                var genericArgumentsBuilders = declaringMethod.DefineGenericParameters(genericArguments.Select(a => a.Name).ToArray());

                for (var index = 0; index < genericArguments.Length; index++)
                {
                    genericArgumentsBuilders[index].SetGenericParameterAttributes(genericArguments[index].GenericParameterAttributes);
                    foreach (var constraint in genericArguments[index].GetGenericParameterConstraints())
                    {
                        if (constraint.IsClass)
                        {
                            genericArgumentsBuilders[index].SetBaseTypeConstraint(constraint);
                        }
                        if (constraint.IsInterface)
                        {
                            genericArgumentsBuilders[index].SetInterfaceConstraints(constraint);
                        }
                    }
                }
            }
예제 #20
0
        private static MethodInfo Create_ConvertByrefToPtr()
        {
            // We dont use AssemblyGen.DefineMethod since that can create a anonymously-hosted DynamicMethod which cannot contain unverifiable code.
            var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("ComSnippets"), AssemblyBuilderAccess.Run);
            var moduleBuilder = assemblyBuilder.DefineDynamicModule("ComSnippets");
            var type = moduleBuilder.DefineType("Type$ConvertByrefToPtr", TypeAttributes.Public);

            Type[] paramTypes = new Type[] { typeof(Variant).MakeByRefType() };
            MethodBuilder mb = type.DefineMethod("ConvertByrefToPtr", MethodAttributes.Public | MethodAttributes.Static, typeof(IntPtr), paramTypes);
            GenericTypeParameterBuilder[] typeParams = mb.DefineGenericParameters("T");
            typeParams[0].SetGenericParameterAttributes(GenericParameterAttributes.NotNullableValueTypeConstraint);
            mb.SetSignature(typeof(IntPtr), null, null, new Type[] { typeParams[0].MakeByRefType() }, null, null);

            ILGenerator method = mb.GetILGenerator();

            method.Emit(OpCodes.Ldarg_0);
            method.Emit(OpCodes.Conv_I);
            method.Emit(OpCodes.Ret);

            return type.CreateType().GetMethod("ConvertByrefToPtr");
        }
예제 #21
0
        public void SetParameters_NullParameter_ThrowsArgumentNullException()
        {
            TypeBuilder   type    = Helpers.DynamicType(TypeAttributes.Abstract);
            MethodBuilder builder = type.DefineMethod("TestMethod", MethodAttributes.Public, typeof(void), new Type[] { typeof(int) });

            Type[] typeParameters = builder.DefineGenericParameters("T").Select(a => a.AsType()).ToArray();

            Type[] parameterTypes = new Type[typeParameters.Length + 1];
            for (int i = 0; i < typeParameters.Length; ++i)
            {
                parameterTypes[i] = typeParameters[i];
            }
            parameterTypes[typeParameters.Length] = null;

            builder.SetParameters(parameterTypes);
            ILGenerator ilGenerator = builder.GetILGenerator();

            ilGenerator.Emit(OpCodes.Ret);

            AssertExtensions.Throws <ArgumentNullException>("argument", () => type.CreateTypeInfo().AsType());
        }
예제 #22
0
        private static void DefineGenericMethodParameters(MethodInfo method, MethodBuilder methodBuilder)
        {
            var typeParameters        = method.GetGenericArguments();
            var typeParameterBuilders = methodBuilder
                                        .DefineGenericParameters(typeParameters.Select(tp => tp.Name).ToArray())
                                        .ToDictionary(b => b.Name);

            SetGenericTypeConstraints(typeParameterBuilders, typeParameters);

            var returnType = method.ReturnType;

            methodBuilder.SetReturnType(
                returnType.IsGenericMethodParameter ? typeParameterBuilders[returnType.Name] : returnType);
            var parameters = method.GetParameters();

            methodBuilder.SetParameters(
                parameters
                .Select(p => p.ParameterType)
                .Select(t => t.IsGenericMethodParameter ? typeParameterBuilders[t.Name] : t)
                .ToArray());
        }
예제 #23
0
        public void SetSignature_GenericMethod_ParameterType_RequiredCustomModifiers()
        {
            TypeBuilder   type   = Helpers.DynamicType(TypeAttributes.Abstract);
            MethodBuilder method = type.DefineMethod("TestMethod", MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual);

            string[] typeParamNames = new string[] { "T" };
            GenericTypeParameterBuilder[] typeParameters =
                method.DefineGenericParameters(typeParamNames);
            GenericTypeParameterBuilder desiredReturnType = typeParameters[0];

            Type[]   desiredParamType = new Type[] { typeof(int) };
            Type[][] parameterTypeRequiredCustomModifiers = new Type[desiredParamType.Length][];
            for (int i = 0; i < desiredParamType.Length; ++i)
            {
                parameterTypeRequiredCustomModifiers[i] = null;
            }

            method.SetSignature(desiredReturnType.AsType(), null, null, desiredParamType, parameterTypeRequiredCustomModifiers, null);

            VerifyMethodSignature(type, method, desiredReturnType.AsType());
        }
예제 #24
0
        /// <summary>
        ///     返回具体类型的对象存储实例
        /// </summary>
        /// <typeparam name="T">处理的类型</typeparam>
        /// <returns>返回一个动态实例</returns>
        public static PropertyValueStored <T> BuildMethod <T>()
        {
            AssemblyBuilder assemblyBuilder     = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Assembly"), AssemblyBuilderAccess.Run);
            ModuleBuilder   defineDynamicModule = assemblyBuilder.DefineDynamicModule("Module");
            TypeBuilder     typeBuilder         = defineDynamicModule.DefineType("KJFramework.DynamicModule.ValueStored", TypeAttributes.Public | TypeAttributes.Class, typeof(PropertyValueStored <T>), new Type[] {});
            MethodBuilder   methodBuilder       = typeBuilder.DefineMethod("Get", MethodAttributes.Public | MethodAttributes.Virtual);

            GenericTypeParameterBuilder[] gpas = methodBuilder.DefineGenericParameters("K");
            methodBuilder.SetParameters(typeof(T));
            methodBuilder.SetReturnType(gpas[0].AsType());
            methodBuilder.DefineParameter(1, ParameterAttributes.None, "value");
            ILGenerator ilGenerator = methodBuilder.GetILGenerator();

            ilGenerator.Emit(OpCodes.Ldarg_1);

            //(T)value
            //ilGenerator.Emit(OpCodes.Castclass, typeof(T));
            ilGenerator.Emit(OpCodes.Ret);

            return((PropertyValueStored <T>)typeBuilder.Assembly.CreateInstance(typeBuilder.CreateTypeInfo().FullName));
        }
예제 #25
0
                public static GenericTypeParameterBuilder[] CreateGenericParametersFrom(
                    MethodBuilder methodBuilder,
                    MethodInfo methodInfo)
                {
                    if (methodBuilder == null)
                    {
                        throw new ArgumentNullException(nameof(methodBuilder));
                    }

                    if (methodInfo == null)
                    {
                        throw new ArgumentNullException(nameof(methodInfo));
                    }

                    var arguments  = methodInfo.GetGenericArguments();
                    var parameters = methodBuilder.DefineGenericParameters(arguments.Select(i => i.Name).ToArray()).ToArray();

                    CopyGenericParametersInformation(parameters, arguments);

                    return(parameters);
                }
예제 #26
0
        public void TestAfterTypeCreated()
        {
            string methodName = null;

            methodName = _generator.GetString(false, false, true, MinStringLength, MaxStringLength);
            Type[] parameterTypes = new Type[] { typeof(int) };

            TypeBuilder   typeBuilder = GetTestTypeBuilder();
            MethodBuilder builder     = typeBuilder.DefineMethod(methodName,
                                                                 TestMethodAttributes,
                                                                 typeof(int),
                                                                 parameterTypes);

            string[] typeParamNames = { "T", "U" };
            GenericTypeParameterBuilder[] typeParameters =
                builder.DefineGenericParameters(typeParamNames);
            Type desiredReturnType = typeParameters[0].AsType();

            typeBuilder.CreateTypeInfo().AsType();

            builder.SetReturnType(desiredReturnType);
        }
예제 #27
0
        public void TestOverwriteGenericReturnTypeWithGenericType()
        {
            string methodName = null;

            methodName = TestLibrary.Generator.GetString(false, false, true, MinStringLength, MaxStringLength);

            TypeBuilder   typeBuilder = GetTestTypeBuilder();
            MethodBuilder builder     = typeBuilder.DefineMethod(methodName,
                                                                 TestMethodAttributes);

            string[] typeParamNames = { "T", "U" };
            GenericTypeParameterBuilder[] typeParameters =
                builder.DefineGenericParameters(typeParamNames);
            Type desiredReturnType = typeParameters[1].AsType();

            builder.SetReturnType(typeParameters[0].AsType());
            builder.SetReturnType(desiredReturnType);

            typeBuilder.CreateTypeInfo().AsType();

            VerifyReturnType(builder, desiredReturnType);
        }
예제 #28
0
        private static MethodBuilder DefineGeneric(this MethodBuilder methodBuilder, MethodInfo method)
        {
            var genericArguments         = method.GetGenericArguments();
            var genericArgumentsBuilders = methodBuilder.DefineGenericParameters(genericArguments.Select(a => a.Name).ToArray());

            genericArguments.ForEach((arg, index) =>
            {
                genericArgumentsBuilders[index].SetGenericParameterAttributes(arg.GenericParameterAttributes);
                arg.GetGenericParameterConstraints().ForEach(constraint =>
                {
                    if (constraint.IsClass)
                    {
                        genericArgumentsBuilders[index].SetBaseTypeConstraint(constraint);
                    }
                    if (constraint.IsInterface)
                    {
                        genericArgumentsBuilders[index].SetInterfaceConstraints(constraint);
                    }
                });
            });
            return(methodBuilder);
        }
예제 #29
0
        public void CreateProxyMethod(
            MethodInfo methodInfo, TypeBuilder typeBuilder)
        {
            ParameterInfo[] paramInfos = methodInfo.GetParameters();
            Type[]          paramTypes = new Type[paramInfos.Length];
            for (int i = 0; i < paramInfos.Length; i++)
            {
                paramTypes[i] = paramInfos[i].ParameterType;
            }

            MethodAttributes methodAttributes =
                MethodAttributes.Public |
                MethodAttributes.Virtual |
                MethodAttributes.HideBySig;

            MethodBuilder methodBuilder =
                typeBuilder.DefineMethod(
                    methodInfo.Name,
                    methodAttributes,
                    CallingConventions.HasThis,
                    methodInfo.ReturnType,
                    paramTypes);

            Type[] genericArgs = methodInfo.GetGenericArguments();

            if (genericArgs != null && genericArgs.Length > 0)
            {
                string[] typeNames = new string[genericArgs.Length];
                for (int i = 0; i < genericArgs.Length; i++)
                {
                    typeNames[i] = "T" + i;
                }
                methodBuilder.DefineGenericParameters(typeNames);
            }

            ILGenerator ilGenerator = methodBuilder.GetILGenerator();

            BuildProxyMethodBody(methodInfo, ilGenerator);
        }
예제 #30
0
        public void ILGen_InstantiatedGenericType()
        {
            TypeBuilder   tb = module.DefineType(genTypeName(), TypeAttributes.Public);
            MethodBuilder mb = tb.DefineMethod("return_type",
                                               MethodAttributes.Public | MethodAttributes.Static, typeof(object), new Type [] { });

            GenericTypeParameterBuilder[] pars = mb.DefineGenericParameters(new string [] { "foo" });

            ILGenerator ilgen = mb.GetILGenerator();

            Type genericFoo = typeof(GenericFoo <int>).GetGenericTypeDefinition().MakeGenericType(new Type [] { pars [0] });

            ilgen.Emit(OpCodes.Ldtoken, genericFoo);
            ilgen.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"));
            ilgen.Emit(OpCodes.Ret);

            Type       t   = tb.CreateType();
            MethodInfo mi  = t.GetMethod("box_int");
            MethodInfo mi2 = mi.MakeGenericMethod(new Type [] { typeof(int) });

            Assert.AreEqual(typeof(GenericFoo <int>), mi2.Invoke(null, new object [] { 1 }));
        }