c#关于反射与特性《一》---动态调用成员
来源:互联网 发布:等式约束优化 数值求解 编辑:程序博客网 时间:2024/06/06 13:02
反射(reflection),按照定义,即为对程序集中的元数据进行检查的过程。而特性,按本人的理解,就是在程序集中插入自定义的元数据标记,为类或类成员(属性,方法,字段等)打上特定的标记,方便查找和调用。在.netFramework框架下,System.Reflection 及提供了充足的反射类型,,(MethodInfo, PropertyInfo, FieldInfo,等)均是在检查元数据过程中非常实用的类。对于反射有个不容忽视的强大特性,那就是在CAS(code-access-security)的前提下,它可以绕过访问等级制度(见以下示例),可以直接调用并对私有成员进行赋值,当然对于代码安全而言也是个不容忽视的漏洞隐患。 另外也因为有了反射和特性,因此出现了新型的编程模型,相对于OOP(面向对象),出现了AOP(面向方面编程,Aspect-oriented programing)足可见其强大。
以下为测试反射和特性的小例子,按照特性来查找类成员,并调用和赋值的例子,其中包括对私有属性和私有方法的访问。
访问私有成员时需要注意BindingFlags.NonPublic 以及为实例还是静态成员的BindingFlags.Instance;
文件1:
using System.IO;using System;using TestAttributes;using System.Reflection;class Program{ static void Main() { var type=typeof(TestClassA); //invoke the methods in TestClassA with ExportAttribute; ExportAttribute.InvokeMethod("TestMethod1",type,null); var parameters=new string[]{"anyname"}; ExportAttribute.InvokeMethod("Print",type,parameters); //set the private property in TestClassA with value; var class1=new TestClassA(); SetPropertyValue(class1,"level","LevelClass1"); class1.Print("anynameclass1"); } //Set property Value; public static bool SetPropertyValue(object target,string propertyName,object propertyValue) { var type=target.GetType(); var property=type.GetProperty(propertyName,BindingFlags.NonPublic|BindingFlags.Instance|BindingFlags.Public); if(property!=null) { var attributes=property.GetCustomAttributes(false); foreach(var attribute in attributes) { if(attribute is ExportAttribute) { property.SetValue(target,propertyValue,null); return true; } } } return false; }}
文件2:
using System.Reflection;using System;using System.IO;namespace TestAttributes{ [AttributeUsage(AttributeTargets.Method|AttributeTargets.Property)] public class ExportAttribute: Attribute { public string catalogs {get;set;} //the classtype must have a default constructor; if the parameter of the method is null ,then the parameters must be null; public static bool InvokeMethod(string MethodName,Type classtype,object[] parameters) { if(MethodName==null||classtype==null) return false; var flag=false; var methodInfos=classtype.GetMethods(BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance); foreach(var info in methodInfos) { if(info.Name==MethodName&&IsHaveExportAttribute(info)) { flag=true; var instance=Activator.CreateInstance(classtype); info.Invoke(instance,parameters); } } return flag; } public static bool IsHaveExportAttribute(MethodInfo info) { if(info==null) { return false; } var attributes=info.GetCustomAttributes(false); foreach (var attribute in attributes) { if(attribute is ExportAttribute) { return true; } } return false; } } public class TestClassA { private string name {get;set;} [Export] private string level {get;set;} public TestClassA() { name="DefaultName"; level="DefaultLevel"; } [Export] private void TestMethod1() { using (StreamReader reader = new StreamReader("input.txt")) { string line; while ((line = reader.ReadLine()) != null) { Console.WriteLine(line); } } Console.ReadKey(); } [Export] public void Print(string name) { Console.WriteLine(name); Console.WriteLine(level); Console.ReadKey(); } }}
输出:
Testing Reflection
**********************
anyname
DefaultLevel
anynameclass1
LevelClass1
- c#关于反射与特性《一》---动态调用成员
- C#利用反射动态调用类成员
- C# 高级应用--反射动态调用类的成员范例 !
- 使用反射动态调用类成员
- 使用反射动态调用类成员
- 利用反射动态调用类成员
- (C#)利用反射动态调用类成员
- 利用反射动态调用类成员(1)
- C#特性与反射机制
- 【经典实例】利用C#反射动态编译代码,创建类的实例,并调用其成员
- 【点滴积累】在C#中使用反射动态调用类型成员
- C#高级应用-反射动态调用类的成员范例代码
- C#属性与特性,方法,反射
- (Java)利用反射动态调用类成员
- (C#)利用反射动态调用类成员
- (Java)利用反射动态调用类成员
- 利用反射动态调用类成员(转)
- 利用反射动态调用组件或类成员
- iOS Tutorial: Create iPhone video chat app using Parse and Opentok (tokbox)
- 黑马程序员——11JavaAPI字符串和对象包装类
- python获取系统信息(系统版本,CPU信息,内存信息,硬盘信息)
- jquery 的模块化
- 第1章、ASP.NET是什么?
- c#关于反射与特性《一》---动态调用成员
- ZOJ 3198 Intersection of Two Sets
- NJUST 1747 Yet another end of the world(13年南京邀请赛-K题-数学)
- day2 test06
- 第2章、hello,world!
- lcx转发3389数据
- Qt Designer 编辑Tab顺序
- 第3章、数据类型与变量
- 黑马程序员——12JavaAPI集合类