.Net的私有属性、成员变量、方法,都可以通过反射获取调用,当然正常我们不会这么操作
此章只是做一个反射科普,像EFCore从数据库取值的底层框架就是通过反射直接操作私有的成员变量,而不是方法。
直接上例子,先定义一个类
public class TenantModel { public int Id { get; init; }//属性,未定义成员变量会自动生成 public string Name { get; set; }//属性 private string password;//成员变量 public string Password//属性 { private get //方法(属性里的get;set;均为方法,或者自己定义一个方法测试) { return password; } set { if (value.Length < 6) throw new Exception("密码需要大于6位"); password = value; } } }
然后利用反射,获取到私有的password信息
1)通过对象进行反射
var te = new TenantModel() { Id = 1, Name = "kxy", Password = "1234567" }; Type type = te.GetType(); //te.GetType().GetMethods(BindingFlags.NonPublic | BindingFlags.Instance);//获取所有私有方法 MethodInfo func1 = type.GetMethod("get_Password", BindingFlags.NonPublic | BindingFlags.Instance);//获取私有方法 var str = func1.Invoke(te, null).ToString();//执行方法 FieldInfo field = type.GetField("password", BindingFlags.NonPublic | BindingFlags.Instance);//获取私有成员变量 string pwd = field.GetValue(te)?.ToString();//取值 field.SetValue(te, "123");//赋值,直接操作成员变量,可以跳过验证
这样就简单实现了一个反射读取私有信息的案例,当然还可以通过程序集反射
2)通过程序集进行反射(因为实例化)
反射也是通过构造函数实例化的,默认为无参,也可以带参,为了展示,我们多定义一个带参构造函数
public TenantModel(int id,string name,string password) { Id = id; Name = name; Password = password; }
然后,反射代码如下:
Assembly assembly = Assembly.Load("ServerSignalR");//反射入口,从程序集加载,ServerSignalR为程序集名称 Type type = assembly.GetType("ServerSignalR.Models.TenantModel");//基于类的完整名称找出类型 TenantModel te = Activator.CreateInstance(type, new object[] { 1, "kxy", "1234567" }) as TenantModel;//实例化 MethodInfo func1 = type.GetMethod("get_Password", BindingFlags.NonPublic | BindingFlags.Instance);//获取私有方法 var str = func1.Invoke(te, null)?.ToString();//执行方法 FieldInfo field = type.GetField("password", BindingFlags.NonPublic | BindingFlags.Instance);//获取私有成员变量 string pwd = field.GetValue(te)?.ToString();//取值 field.SetValue(te, "123");//赋值,直接操作成员变量,可以跳过验证
也可以选定dll文件
Assembly assembly = null; //注意区分开发和生产环境 if (_env.IsDevelopment()) { assembly = Assembly.LoadFrom("bin//Debug//net5.0//ServerSignalR.dll");//dll的路径 } else { assembly = Assembly.LoadFrom("ServerSignalR.dll");//dll的路径 } Type type = assembly.GetType("ServerSignalR.Models.TenantModel");//基于类的完整名称找出类型 TenantModel te = Activator.CreateInstance(type, new object[] { 1, "kxy", "1234567" }) as TenantModel;//实例化 MethodInfo func1 = type.GetMethod("get_Password", BindingFlags.NonPublic | BindingFlags.Instance);//获取私有方法 var str = func1.Invoke(te, null)?.ToString();//执行方法 FieldInfo field = type.GetField("password", BindingFlags.NonPublic | BindingFlags.Instance);//获取私有成员变量 string pwd = field.GetValue(te)?.ToString();//取值 field.SetValue(te, "123");//赋值,直接操作成员变量,可以跳过验证
至此,完毕!!!
感谢关注