前言:
学编程一年多,现在才真正开始用反射,有点晚了,但是用好反射真的很重要,算是很方便,这么久了不会用反射,其实是有一小点点的low的,所以准备好好学习一下,写博客记录一下,权当笔记和动力了.\*^_^*/What-反射是什么?
反射,Reflection,就是通过一个类对象,可以获取他所在类的其他全部成员和属性,包括私有的.Why-为什么要使用发射?
##1.获取该成员的其他属性信息来使用
例如我想写个导出表格,但是列名想定义在对应的实体类model中,好一一对应,代码侵入性小,容易维护,于是自定义了一个注解,放在这个model需要导出的变量上,我需要将这个model的对象作为方法传入,然后拿出这个类所有对象成员变量上定义的这个自定义属性.##2.配合泛型,写出通用的一个工具类,一般用于框架性的代码
例如:接着上个例子,我现在有两个表格要导出,部门表和员工表,所以有两个类,部门model,员工model.这个时候,可以使用泛型类型传参,然后通过反射获取传过来的类型的自定义注解信息##3.例如反射获取一个类的私有方法或者属性
例如:需要用到一个类里面的方法,但是这个方法是不对外暴露的,怎么办?我们不怕,因为我们有反射.#How-使用反射Start
首先我们定义这么一个类,分别定义的public,protected,private修饰的字段,属性,方法.,下面我们用反射获取试一下.
namespace ConsoleApplication1
{
public enum GenderEnum
{
Boy = 0,
Girl = 1,
Dog = 2
}
public class WorkerModel
{
/// <summary>
/// 字段
/// </summary>
public string _name = "Hathway";
private int _id = 32;
protected bool _isAdmin = true;
public GenderEnum _gender = GenderEnum.Girl;
/// <summary>
/// 属性
/// </summary>
public string Name { get; set; }
public GenderEnum Gender { get; set; }
private int Id { get; set; }
protected bool isAdmin { get; set; }
/// <summary>
/// 方法
/// </summary>
public void Android()
{
}
protected void iOS()
{
}
private void WindowPhone()
{
}
/// <summary>
/// 构造方法
/// </summary>
public WorkerModel()
{
}
public WorkerModel(string name, int id, GenderEnum gender, bool isAdmin)
{
}
}
定义这个类对象,我们去使用反射获取一下这个对象的各类信息
WorkerModel worker = new WorkerModel() {
Name = "Jay",
Gender = GenderEnum.Boy,
};
1.字段信息—FieldInfo----type.getGetFields()
public static void GetFieldValue(Object obj)
{
//得到对象的类型
Type type = obj.GetType();
//得到字段的值,只能得到public类型的字典的值
FieldInfo[] fieldInfos = type.GetFields();
foreach (var f in fieldInfos)
{
//字段名称
string fieldName = f.Name;
//字段类型
string fieldType = f.FieldType.ToString();
//字段的值
string fieldValue = f.GetValue(obj).ToString();
Console.WriteLine("fieldName------>" + fieldName );
Console.WriteLine( "fieldType------>" + fieldType );
Console.WriteLine("fieldValue------>" + fieldValue);
Console.WriteLine("-------------------------------------------------------------------");
}
}
2.属性信息—PropertyInfo----type.GetProperties()
public static void GetPropertyInfo(Object obj)
{
Type type = obj.GetType();
PropertyInfo[] propertyInfo = type.GetProperties();
foreach (var p in propertyInfo)
{
string propertyName = p.Name
string propertyValue = p.GetValue(obj,null).ToString();
Console.WriteLine("propertyName------>" + propertyName);
Console.WriteLine("propertyValue----->" + propertyValue);
Console.WriteLine("-------------------------------------------------------------------");
}
}
3.方法信息—MethodInfo----type.GetMethods()
public static void GetMethodInfo(Object obj)
{
Type type = obj.GetType();
//获取所有public修饰的方法
MethodInfo[] methodInfo = type.GetMethods();
foreach (var m in methodInfo)
{
string methodName = m.Name;
Console.WriteLine("methodName------>" + methodName);
Console.WriteLine("-------------------------------------------------------------------");
}
}
4.成员信息—MemberInfo----type.GetMembers()
public static void GetMemberInfo(Object obj)
{
Type type = obj.GetType();
MemberInfo[] memberInfo = type.GetMembers();
foreach (var m in memberInfo)
{
string memberName = m.Name;
Console.WriteLine("memberName------>" + memberName);
Console.WriteLine("-------------------------------------------------------------------");
}
}
5.构造方法信息—ConstructorInfo----type.GetConstructors()
private static void GetConstructorInfo(Object obj)
{
Type type = obj.GetType();
//获取所有public修饰的构造方法
ConstructorInfo[] constructorInfo = type.GetConstructors();
foreach (var c in constructorInfo)
{
string constructorName = c.Name;
ParameterInfo[] constructorParams = c.GetParameters();
Console.WriteLine("constructorName------>" + constructorName);
foreach (var p in constructorParams)
{
Console.WriteLine("Params------ p.Name-->" + p.Name);
Console.WriteLine("Params------ p.Type--->"+ p.ParameterType);
}
Console.WriteLine("-------------------------------------------------------------------");
}
}
public怎么够? 获取受保护的成员信息
现在获取私有属性的请问激动不激动,按耐住,完全出乎你的意料,只需要改动一句代码就好了, 以GetFields为例:1.获取public修饰
//得到字段的值,只能得到public类型的字典的值
FieldInfo[] fieldInfos = type.GetFields();
2.获取private 和protected的值
//获取全部类型的值
FieldInfo[] fieldInfos = type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
看我们使用第二个方法得到的字段信息是怎样的呢,打印出来看看:
哈哈,很明显,我们获取了所有的字段,连属性默认创建的隐藏字段都打印出来了,看来获取的方式是正确的.剩下的Method,Member等就不贴图了,说实话,这个图黑底白字看着好刺眼,贴的还心塞,大家下去可以打印看看,会发现很多你想不到的方法哟~~
好了,回归主题,注意观察,我们用的是同一个方法名,只是传递的是参数不同,是不同的方法重写而已,如下:
//
// 摘要:
// 返回当前 System.Type 的所有公共字段。
//
// 返回结果:
// 表示为当前 System.Type 定义的所有公共字段的 System.Reflection.FieldInfo 对象数组。 - 或 - 如果没有为当前
// System.Type 定义的公共字段,则为 System.Reflection.FieldInfo 类型的空数组。
public FieldInfo[] GetFields();
//
// 摘要:
// 当在派生类中重写时,使用指定绑定约束,搜索为当前 System.Type 定义的字段。
//
// 参数:
// bindingAttr:
// 一个位屏蔽,由一个或多个指定搜索执行方式的 System.Reflection.BindingFlags 组成。 - 或 - 零,以返回 null。
//
// 返回结果:
// 表示为当前 System.Type 定义的匹配指定绑定约束的所有字段的 System.Reflection.FieldInfo 对象数组。 - 或
// - 如果没有为当前 System.Type 定义的字段,或者如果没有一个定义的字段匹配绑定约束,则为 System.Reflection.FieldInfo
// 类型的空数组。
public abstract FieldInfo[] GetFields(BindingFlags bindingAttr);
最后
很晚了,回去睡觉了,这周有时间,会专门抽时间看一下关于BindFlags的具体使用.因为我试的时候发现必须要加上BindFlags.Instance参数,否则就获取不到,强迫症一定要知道是为什么,找到答案后会写篇博客的. 晚安,csdn,晚安,大家,晚安,自己^_^想知道BindFlags.Instance为什么一定要使用的小伙伴们点这里.
欢迎关注个人微信公众号「浅浅同学的开发笔记」,最新的博客,好玩的事情,都会在上面分享,期待与你共同成长。