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

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

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!

时间: 2024-10-31 06:53:17

Emit:动态给一个类型添加Attribute的相关文章

属性-怎么在mvc3中动态给类中的property添加attribute?

问题描述 怎么在mvc3中动态给类中的property添加attribute? 有一个类A public class A{ public int Id{get;set;} public stirng Name{get;set;} } 通过反射将A中的property保存到txt文件中了,保存如下 Id.DisplayName=Id Name.DisplayName=Name 修改txt文件 Id.DisplayName=编号 Name.DisplayName=姓名 我想通过修改txt中的文件然后

[android]我想知道是否能够设置软键盘输入切换到下一个EditText动态改变输入类型?

问题描述 [android]我想知道是否能够设置软键盘输入切换到下一个EditText动态改变输入类型? 问题,假设有2个EditText,第一个inputType=text,第二个也是text的.我想这么做,在第一个软键盘弹出后,我换了输入类型是numer,下一步切换到第二个Edittext,软键盘会自动改变类型为text的键盘界面,我希望能通过什么方法,保证软键盘不会自动切换类型.

如何在程序运行时动态修改一个类的属性的get;set;?

问题描述 publicclassMyTestClass{privatestring_name;publicstringName{get{returnstring.Format("名字:{0}",_name);}set{value=value??string.Empty;_name=value.Substring(0,4);}}}publicstaticvoidMain(){DynamicMethodmethod=newDynamicMethod("Set_Name"

Ext中如何动态生成一个form表单

问题描述 Ext中如何动态生成一个form表单,主要是表单里的item配置是会变的,根据数据库的数据会变.怎样动态生成这个表单呢. 问题补充:lizhi92574 写道 解决方案 var item, items = form.getForm().items;while ((item = items.last())) { //删除组件form.getForm().remove(item);form.remove(item);}form.add();//添加组件form.doLayout();解决方

Android实现动态向Gallery中添加图片及倒影与3D效果示例_Android

本文实例讲述了Android实现动态向Gallery中添加图片及倒影与3D效果的方法.分享给大家供大家参考,具体如下: 在Android中gallery可以提供一个很好的显示图片的方式,实现上面的效果以及动态添加数据库或者网络上下载下来的图片资源.我们首先实现一个自定义的Gallery类. MyGallery.java: package nate.android.Service; import android.content.Context; import android.graphics.Ca

Android实现动态向Gallery中添加图片及倒影与3D效果示例

本文实例讲述了Android实现动态向Gallery中添加图片及倒影与3D效果的方法.分享给大家供大家参考,具体如下: 在Android中gallery可以提供一个很好的显示图片的方式,实现上面的效果以及动态添加数据库或者网络上下载下来的图片资源.我们首先实现一个自定义的Gallery类. MyGallery.java: package nate.android.Service; import android.content.Context; import android.graphics.Ca

javascript动态创建表格及添加数据实例详解

  本文实例讲述了javascript动态创建表格及添加数据的方法.分享给大家供大家参考.具体分析如下: 1. 动态创建表格(代码不兼容IE6) ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv=&qu

【Android】Android动态代理为SurfaceHolder添加Hook

本博客将会介绍动态代理在Android应用中的一种使用场景 代理模式 代理模式的作用是为其它对象提供一种代理以控制对这个对象的访问.比如用户调用了一个"吃饭"的方法,如果不依靠代理,用户可能自己拿碗饭吃就行,而如果通过代理的话,可能连碗都不需要用户自己拿,用户只需要张开嘴,代理来喂就行了,需要注意的是,这里代理除了负责拿碗和喂饭外还可以做其他的任何事情,比如说帮你把饭吹凉一些,或者担心你的体重而偷偷帮你倒掉了一半的饭,又或者是往饭里加点什么奇奇怪怪的东西,谁知道呢,这就是代理干的活.实

在jsp页面上动态生成一个数组,如何通过按钮点击事件将数组显示在一个textarea里

问题描述 在jsp页面上动态生成一个数组,如何通过按钮点击事件将数组显示在一个textarea里 在jsp页面上动态生成一个数组,如何通过按钮点击事件将数组显示在一个textarea里 解决方案 按钮添加click事件,直接document.getElementById('textarea的id').value=arr[需要显示的数据项下标] 解决方案二: 先得到数组,比如说是arrA,然后var strVal = JSON.stringify(arrA);这是把把一个数据对像转换成字符串.然后