Emit:动态给一个类型添加Attribute

2019-09-12 09:39:14 浏览数 (2)

下面这段代码整理自sl4的官方文档,已经加了详细的注释,相信大家都能看明白:

代码语言:javascript复制
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;

namespace CustomAttributeBuilderSample
{

    public class DemoClass
    {
        static void Main(string[] args)
        {

            //得到新类型
            Type myType = BuildTypeWithCustomAttributesOnMethod();

            //创建myType的实例
            object myInstance = Activator.CreateInstance(myType);

            //获取myType上应用的所有Attribute
            object[] customAttrs = myType.GetCustomAttributes(true);

            Console.WriteLine("Custom Attributes for Type 'MyType':"   "n");
            object attrVal = null;

            foreach (object customAttr in customAttrs)
            {
                //获取ClassCreatorAttribute中的Creator属性值
                attrVal = typeof(ClassCreatorAttribute).InvokeMember("Creator", BindingFlags.GetProperty, null, customAttr, new object[] { });
                Console.WriteLine(String.Format("-- Attribute: [{0} = "{1}"]", customAttr, attrVal)   "n");
            }

            Console.WriteLine("Custom Attributes for Method 'HelloWorld()' in 'MyType':"   "n");
            //获取myType中的HelloWorld方法上的所有Attribute
            customAttrs = myType.GetMember("HelloWorld")[0].GetCustomAttributes(true);

            foreach (object customAttr in customAttrs)
            {
                //获取DateLastUpdatedAttribute的DateUpdated属性值
                attrVal = typeof(DateLastUpdatedAttribute).InvokeMember("DateUpdated", BindingFlags.GetProperty, null, customAttr, new object[] { });
                Console.WriteLine(String.Format("-- Attribute: [{0} = "{1}"]", customAttr, attrVal)   "n");
            }

            Console.WriteLine("---"   "n");
            //动态调用myType实例中的HelloWorld方法
            Console.WriteLine(myType.InvokeMember("HelloWorld", BindingFlags.InvokeMethod, null, myInstance, new object[] { })   "n");


            Console.ReadKey();
        }

        /// <summary>
        /// 创建一个应用了ClassCreatorAttribute、DateLastUpdatedAttribute的类型
        /// </summary>
        /// <returns></returns>
        public static Type BuildTypeWithCustomAttributesOnMethod()
        {

            AppDomain currentDomain = Thread.GetDomain();

            AssemblyName myAsmName = new AssemblyName();
            myAsmName.Name = "MyAssembly";

            //动态创建一个程序集
            AssemblyBuilder myAsmBuilder = currentDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.Run);

            //动态创建一个模块
            ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule("MyModule");

            //动态创建一个类型:MyType
            TypeBuilder myTypeBuilder = myModBuilder.DefineType("MyType", TypeAttributes.Public);

            //定义构造器参数
            Type[] ctorParams = new Type[] { typeof(string) };

            //获取构造器信息
            ConstructorInfo classCtorInfo = typeof(ClassCreatorAttribute).GetConstructor(ctorParams);

            //动态创建ClassCreatorAttribute
            CustomAttributeBuilder myCABuilder = new CustomAttributeBuilder(
                           classCtorInfo,
                           new object[] { "Joe Programmer" });

            //将上面动态创建的Attribute附加到(动态创建的)类型MyType
            myTypeBuilder.SetCustomAttribute(myCABuilder);

            //动态创建一个无返回值,无参数的,公有方法HelloWorld
            MethodBuilder myMethodBuilder = myTypeBuilder.DefineMethod("HelloWorld", MethodAttributes.Public, null, new Type[] { });

            ctorParams = new Type[] { typeof(string) };

            //获取DateLastUpdatedAttribute的构造函数信息
            classCtorInfo = typeof(DateLastUpdatedAttribute).GetConstructor(ctorParams);

            //动态创建DateLastUpdatedAttribute
            CustomAttributeBuilder myCABuilder2 = new CustomAttributeBuilder(
                           classCtorInfo,
                           new object[] { DateTime.Now.ToString() });

            //将上面动态创建的Attribute附加到(动态创建的)方法HelloWorld
            myMethodBuilder.SetCustomAttribute(myCABuilder2);

            ILGenerator myIL = myMethodBuilder.GetILGenerator();
            myIL.EmitWriteLine("Hello, world!");//在HelloWorld方法中,创建一行等效于Console.Write("Hello,world!");的代码
            myIL.Emit(OpCodes.Ret);//HelloWorld方法的return语句

            return myTypeBuilder.CreateType();

        }


    }



    /// <summary>
    /// 创建一个自定义的Attribute,稍后将它应用在动态创建的“类型”上
    /// </summary>
    public class ClassCreatorAttribute : Attribute
    {
        private string creator;
        public string Creator
        {
            get
            {
                return creator;
            }
        }

        public ClassCreatorAttribute(string name)
        {
            this.creator = name;
        }

    }

    /// <summary>
    /// 创建一个自定义的Attribute,稍后将它应用在动态创建的“方法”上
    /// </summary>
    public class DateLastUpdatedAttribute : Attribute
    {
        private string dateUpdated;
        public string DateUpdated
        {
            get
            {
                return dateUpdated;
            }
        }

        public DateLastUpdatedAttribute(string theDate)
        {
            this.dateUpdated = theDate;
        }

    }


}

运行输出结果:

Custom Attributes for Type 'MyType':

-- Attribute: [CustomAttributeBuilderSample.ClassCreatorAttribute = "Joe Program mer"]

Custom Attributes for Method 'HelloWorld()' in 'MyType':

-- Attribute: [CustomAttributeBuilderSample.DateLastUpdatedAttribute = "2011/11/ 13 21:46:31"]

---

Hello, world!

0 人点赞