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!

posted @   菩提树下的杨过  阅读(5909)  评论(1编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
历史上的今天:
2009-11-13 silverlight中顺序/倒序异步加载多张图片
2009-11-13 silverlight中如何将string(字符串)写入Resource(资源)?
2009-11-13 silverlight中的几个冷门标记 {x:Null},d:DesignWidth,d:DesignHeight
2008-11-13 WCF与IIS集成Windows身份验证的矛盾
点击右上角即可分享
微信分享提示