反射的常用方法
1、通过反射创建一个实体类
第一种方法,通过Assembly加载程序集的方法
Assembly assembly = Assembly.Load("反射");//加载程序集 Type type = assembly.GetType("反射.MySqlHelper");//加载类型,要求必须是完全限定名,这里不可以写Type type = assembly.GetType("MySqlHelper") object obj = Activator.CreateInstance(type);//创建MySqlHelper实例对象
第二种方法,直接通过实体类的类型
Type type = typeof(People); object o = Activator.CreateInstance(type);
第一种方法适用于需要从外部程序集中加载类的方法;
第二种方法适用于需要反射创建的类就在程序集的内部;
但是,如果Activator.CreateInstance得到的是一个object对象,如果要得到指定的类型需要强转,如下:
Type type = typeof(People); People p = (People)Activator.CreateInstance(type);
或者使用泛型方法(推荐):
People p = Activator.CreateInstance<People>();
2、通过反射实现程序扩展
例如实现多种数据库的访问,现有数据库为Mysql,如果需要增加SQL server数据库访问
第一步,首先创建一个接口IDBHelper
第二步,其实创建MysqlHelper和SqlServerHelper类分别实现IDBHelper接口:
第三步,在App.config文件中添加数据库配置
第四步,创建一个工厂类
第五步,调用IDBHelper
如果需要修改调用的数据库,可以在第三步的配置文件中修改调用数据库的配置文件即可。
3、通过反射实现对象属性的设置:
新建一个People类,正常设置People类采用以下方法:
People people = new People(); people.Id = 123; people.Name = "jim"; people.Address = "china"; people.Description = "make china great again"; Console.WriteLine($"people.Id ={people.Id}"); Console.WriteLine($"people.Name={people.Name}"); Console.WriteLine($"people.Address={people.Address}"); Console.WriteLine($"people.Description={people.Description}");
如果通过反射来读写属性或字段的值,方法如下:
//使用反射 Type type = typeof(People); object o = Activator.CreateInstance(type); foreach (var prop in type.GetProperties()) { //设置属性值 if (prop.Name=="Id") { prop.SetValue(o, 234); } if (prop.Name == "Name") { prop.SetValue(o, "tom"); } if (prop.Name =="Address") { prop.SetValue(o, "usa"); } } foreach (var prop in type.GetProperties()) { //获取属性值 Console.WriteLine($"{type.Name}.{prop.Name} ={prop.GetValue(o)}"); }
//字段的读写 foreach (var field in type.GetFields()) {
//给字段赋值 if (field.Name == "Description") { field.SetValue(o, "make usa great again"); } //获取字段的值 Console.WriteLine($"{type.Name}.{field.Name} ={field.GetValue(o)}"); }
4、使用反射+泛型,读取数据库并将数据赋值给实体类
首先,先不适用反射和泛型,使用常规方法实现如下:
//常规方法 public Company FandCompanyById(int id) { Company company = new Company(); string sqlStr = @"select [Id],[Name],[CreatTime],[CreatorName],[Address] from [Company] where Id =" + id.ToString(); using(SqlConnection conn = new SqlConnection("connectionString")) { SqlCommand cmd = new SqlCommand(sqlStr, conn); conn.Open(); SqlDataReader reader = cmd.ExecuteReader(); if (reader.Read ())//有数据 { company.Id = int.Parse(reader["Id"].ToString()); company.Name = reader["Name"].ToString(); company.CreatTime = DateTime.Parse(reader["CreatTime"].ToString()); company.CreatorName = reader["CreatorName"].ToString(); company.Address = reader["Address"].ToString(); } } return company; }
使用反射+泛型,实现方法如下:、
//使用泛型+反射 public T FandTById<T>(int id) { Type type = typeof(T); T t = (T) Activator.CreateInstance(type); string columnStr = string.Join(",", type.GetProperties().Select(p => $"[{p.Name}]")); string sqlStr = $"select {columnStr} from [{type.Name}] where Id = {id}"; using (SqlConnection conn = new SqlConnection("connectionString")) { SqlCommand cmd = new SqlCommand(sqlStr, conn); conn.Open(); SqlDataReader reader = cmd.ExecuteReader(); if (reader.Read())//有数据 { foreach (var prop in type.GetProperties()) { prop.SetValue(t, reader[prop.Name]); } } } return t; }