[开发故事]第四回:应用反射在运行时动态获取类型信息
2009-05-12 11:21
369 查看
anytao.net | [b]《你必须知道的.NET》网站[/b] | Anytao技术博客
发布日期:2009.05.12 作者:Anytao
© 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处。
开发故事,开发中的小故事。
我的回答是:当然可以了:-)那么,关于怎么做,就是个小问题。
呵呵,那么我们就一个小例子来技术如何在运行时通过反射获取MyAttribute中的字符串信息。
[你必须知道的.NET]第二十四回:认识元数据和IL(上)
[你必须知道的.NET]第二十五回:认识元数据和IL(中)
[你必须知道的.NET]第二十六回:认识元数据和IL(下)
有兴趣可以参考一下。
所以,动态获取类型信息,是反射的拿手好戏,为了做以简单的说明,我就针对hbfly提出的问题实现一个解决方案,首先实现一个自定义的TextAttribute:
其中定义了一个Text字段用于标记在运行时获取的信息,例如:
那么,我们的目的就是在运行时动态获取为Hello类标识的“Hello, Anytao”信息。
为了应用的简单性,我打算对object进行扩展,实现一个GetAttributeText 扩展方法,在实际的应用中,除特殊情况不建议对object实现扩展,否则将造成全局性的扩展,对于框架而言并非好事儿。好了,我们继续,看看如何在扩展方法中应用反射来实现想要的动态效果:
哈哈,大功告成。其实对hbfly而言,最重要的关注就在于通过反射的手段实现对于Attribute信息的读取,在我们的示例中,就是通过GetCustomAttributes方法来实现的。同样的道理,在Type类中还定义了很多的方法应用在不同的目标元素上,例如:
GetEvents/GetEvent
GetConstructors/GetConstructor
GetFields/GetField
GetGenericArguments
GetInterface
GetMembers/GetMember
GetMethods/GetMethod
GetNestedTypes/GetNestedType
GetProperties/GetProperty
……
有了自定义的TextAttribute,有了对于object的扩展方法GetAttributeText,我们就可以实现动态获取类型信息的目标了:
不信,你运行试试。
发布日期:2009.05.12 作者:Anytao
© 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处。
//5.12,愿逝者安息,生者坚强
开发故事,开发中的小故事。
引言
网友hbfly,对于我在[你必须知道的.NET]第三十回:.NET十年(下)一文中关于“当应用attribute进行运行时反射”的论述,希望举例说明,他提出了自己的想法:[MyAttribute("text.....")] public mymethod() { //我可以再方法内部得到attrib的text吗? }
我的回答是:当然可以了:-)那么,关于怎么做,就是个小问题。
呵呵,那么我们就一个小例子来技术如何在运行时通过反射获取MyAttribute中的字符串信息。
实现
既然是在运行时动态获取信息,那么这意味着我们可以通过反射获取任何类型信息,包括:Type、MethodInfo、PropertyInfo、FieldInfo、ParameterInfo都是可以手到擒来的。通过反射如何获取,而这些信息如何而来,我用三篇文章对此进行过详细的论述:[你必须知道的.NET]第二十四回:认识元数据和IL(上)
[你必须知道的.NET]第二十五回:认识元数据和IL(中)
[你必须知道的.NET]第二十六回:认识元数据和IL(下)
有兴趣可以参考一下。
所以,动态获取类型信息,是反射的拿手好戏,为了做以简单的说明,我就针对hbfly提出的问题实现一个解决方案,首先实现一个自定义的TextAttribute:
// Release : code01, 2009/05/12 // Author : Anytao, http://www.anytao.com [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] public sealed class TextAttribute : Attribute { private readonly string text; public TextAttribute(string text) { this.text = text; } public string Text { get { return this.text; } } }
其中定义了一个Text字段用于标记在运行时获取的信息,例如:
// Release : code02, 2009/05/12 // Author : Anytao, http://www.anytao.com [Text("Hello, Anytao")] public class Hello { }
那么,我们的目的就是在运行时动态获取为Hello类标识的“Hello, Anytao”信息。
为了应用的简单性,我打算对object进行扩展,实现一个GetAttributeText 扩展方法,在实际的应用中,除特殊情况不建议对object实现扩展,否则将造成全局性的扩展,对于框架而言并非好事儿。好了,我们继续,看看如何在扩展方法中应用反射来实现想要的动态效果:
// Release : code03, 2009/05/12 // Author : Anytao, http://www.anytao.com public static class TextAttributeExtension { public static string GetAttributeText(this object obj) { Type t = obj.GetType(); var attr = t.GetCustomAttributes(typeof(TextAttribute), true).SingleOrDefault(); if (attr == null) { throw new Exception("There is no TextAttribute to " + t.Name.ToString()); } return ((TextAttribute)attr).Text; } }
哈哈,大功告成。其实对hbfly而言,最重要的关注就在于通过反射的手段实现对于Attribute信息的读取,在我们的示例中,就是通过GetCustomAttributes方法来实现的。同样的道理,在Type类中还定义了很多的方法应用在不同的目标元素上,例如:
GetEvents/GetEvent
GetConstructors/GetConstructor
GetFields/GetField
GetGenericArguments
GetInterface
GetMembers/GetMember
GetMethods/GetMethod
GetNestedTypes/GetNestedType
GetProperties/GetProperty
……
有了自定义的TextAttribute,有了对于object的扩展方法GetAttributeText,我们就可以实现动态获取类型信息的目标了:
// Release : code04, 2009/05/12 // Author : Anytao, http://www.anytao.com static void Main(string[] args) { Hello hello = new Hello(); Console.WriteLine(hello.GetAttributeText()); MyClass mc = new MyClass(); Console.WriteLine(mc.GetAttributeText()); }
不信,你运行试试。
结论
一个简单的技巧,一个补充的说明(对hbfly老兄的)。反射的能量是强大的,强大到我们可以轻而易举的对元数据信息进行读取和操作,正是如此很多基于Attribute和Reflection的巧妙设计就油然而生了。例如,在我的项目中就通过定义Attribute来实现实体类的string属性在get/set时统一进行Trim操作,保证了提交数据没有冗余,同时不必在其他地方来特别关注实现对于string.Trim()的调用。参考文献
你必须知道的.NET更多精彩,尽在anytao.net
相关文章推荐
- 动态加载外部程序集并用反射获取指定类型的信息
- Java反射的高级应用,模拟开发环境IDE动态搜索类成员以及方法,。。。。。
- C#利用反射动态调用DLL并返回结果,和获取程序集的信息
- c++ 完备的运行时类型信息(动态类型信息)
- 利用反射机制动态获取对象属性名称及数据类型
- Shell应用 之 系统信息及运行状态获取
- 第十四章 类型信息 反射 动态代理 空对象 接口和类型信息
- java基础-反射2(反射,反射操作对象,Class对象的使用,类型信息的获取)
- 反射的应用(1)---获取类中各成分的信息
- ios开发不越狱获取本地应用列表通过调用运行时库
- java获取当前应用的运行信息(内存,线程,运行时间,状态等)
- 关于多语言获取手机正在运行应用信息失败
- C++运行时获取类型信息的type_info类与bad_typeid异常
- Java 反射 —— 运行时的类型信息
- Android开发之通过包管理器获取安装应用信息
- JAVA反射--动态加载类--获取方法信息--获取成员变量构造函数信息
- Java的反射与RTTI(运行时类型信息)的区别
- Unity3D的SystemInfo类,用于获取运行设备硬件信息(CPU、显卡、类型等)
- Unity3D的SystemInfo类,用于获取运行设备硬件信息(CPU、显卡、类型等)
- 反射 - 获取运行时方法的信息