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

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

下面这段代码整理自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!

目录
相关文章
16avalon - 指令ms-attr(属性绑定)
16avalon - 指令ms-attr(属性绑定)
69 1
|
12月前
通过Function获取属性对应字段
通过Function获取属性对应字段
67 0
|
2月前
|
存储 JSON JavaScript
组件的创建,引用,样式隔离以及methods,data,properties和数据事件监听
详细介绍了微信小程序中组件的创建、引用(包括局部引用和全局引用)、样式隔离、组件的data、methods和properties,以及组件的数据监听器的使用方法和场景。
组件的创建,引用,样式隔离以及methods,data,properties和数据事件监听
|
3月前
|
开发框架 .NET 编译器
总结一下 C# 如何自定义特性 Attribute 并进行应用
总结一下 C# 如何自定义特性 Attribute 并进行应用
|
6月前
|
JavaScript
为什么data属性是一个函数而不是一个对象?
为什么data属性是一个函数而不是一个对象?
83 1
|
数据安全/隐私保护
input中常用的type属性与使用场景
input中常用的type属性与使用场景
59 0
|
前端开发 JavaScript 开发者
为 class 创建的组件传递 props 参数并直接使用 this.props 来访问|学习笔记
快速学习为 class 创建的组件传递 props 参数并直接使用 this.props 来访问
157 0
为 class 创建的组件传递 props 参数并直接使用  this.props 来访问|学习笔记
element-ui中的Select选择器中remote-method方法带自定义参数
element-ui中的Select选择器中remote-method方法带自定义参数
|
JavaScript 前端开发
为class创建的组件传递props参数并直接使用this.props来访问
为class创建的组件传递props参数并直接使用this.props来访问
为class创建的组件传递props参数并直接使用this.props来访问
|
Linux C语言
利用__attribute__((section()))构建初始化函数表【转】
转自: https://mp.weixin.qq.com/s?__biz=MzAwMDUwNDgxOA==&mid=2652663356&idx=1&sn=779762953029c0e0946c22ef2bb0b754&chksm=810f28a1b678a1b747520ba3ee47c9e...
1760 0
下一篇
无影云桌面