反射
一、课前准备
现在有三个类,分别是:
- 接口
interface DBHelper
{
void AddRecord(int i);
}
- 实现接口类1 MySqlDb
class MySqlDb : DBHelper
{
public void AddRecord(int i)
{
Console.WriteLine("这里使用的是MySql数据库新增一条记录");
}
}
- 实现接口类2 SqlServerDB
class SqlServerDB : DBHelper
{
public void AddRecord(int i)
{
Console.WriteLine("这里使用的是SqlServer数据库新增一条记录");
}
}
二、反射引入
- 普通定义并使用对象
DBHelper hhDB = new MySqlDb();
hhDB.AddRecord();
- 利用反射定义并使用对象方法1:通过程序集名称
Assembly assembly = Assembly.Load("hh反射");//获取程序集名称,它会把这个程序集下所有的相关信息存到assembly对象中,如属性存到对象下的CustomAttributes,类存到对象下的DefinedTypes
Type type = assembly.GetType("hh反射.MySqlDb");//获取命名空间下的类
dynamic oDB = Activator.CreateInstance(type);//创建获得类的对象
MethodInfo method = type.GetMethod("AddRecord");//获得类下的方法
method.Invoke(oDB, new Object[] {1}); //调用方法
- 其中程序集名称是:
- 利用反射定义并使用对象方法2:通过dll路径/exe路径
Assembly assembly = Assembly.LoadFile("F:\\学习盘\\hh反射\\bin\\Debug\\hh反射.exe");//它会把这个程序集下所有的相关信息存到assembly对象中,如属性存到对象下的CustomAttributes,类存到对象下的DefinedTypes
Type type = assembly.GetType("hh反射.MySqlDb");//获取命名空间下的类
dynamic oDB = Activator.CreateInstance(type);//创建获得类的对象
MethodInfo method = type.GetMethod("AddRecord");//获得类下的方法
method.Invoke(oDB, new Object[] {1}); //调用方法
- 利用反射定义并使用对象方法3:由已定义对象获得
DBHelper hhDB = new MySqlDb();
hhDB.AddRecord(2);
Type type = hhDB.GetType();
dynamic oDB = Activator.CreateInstance(type);//创建获得类的对象
MethodInfo method = type.GetMethod("AddRecord");//获得类下的方法
method.Invoke(oDB, new Object[] {1}); //调用方法
三、反射基本应用
接口:DBHelper
实现类1:MySqlDb
实现类2:SqlServerDB
上述的三个类,MySqlDb和SqlServerDB都是继承与接口DBHelper,即实现类不直接依赖细节而是依赖抽象(接口),即下面使用的对象都是定义为抽象(接口)DBHelper类型的,这样的好处就是只要抽象(接口)不变,我上层的代码就不需要改变。假如实际项目中需要把数据库MySqlDb改为SqlServerDB数据库可以通过下面实现:
- 假如项目中本来是应用MySqlDb
DBHelper hhDB = new MySqlDb();
hhDB.AddRecord();
- 现改为SqlServerDB
DBHelper hhDB = new SqlServerDB ();
hhDB.AddRecord();
- 上面只对New后的类型修改即可,仍然是需要修改代码,假如项目中一开始就是利用反射来调用数据库。那么需要这样修改:
- 反射调用时本来是应用MySqlDb
Assembly assembly = Assembly.Load("hh反射");//获取程序集名称,它会把这个程序集下所有的相关信息存到assembly对象中,如属性存到对象下的CustomAttributes,类存到对象下的DefinedTypes
Type type = assembly.GetType("hh反射.MySqlDb");
dynamic oDB = Activator.CreateInstance(type);//创建获得类的对象
MethodInfo method = type.GetMethod("AddRecord");//获得类下的方法
method.Invoke(oDB, new Object[] {1}); //调用方法
- 反射调用时现改为SqlServerDB
Assembly assembly = Assembly.Load("hh反射");//获取程序集名称,它会把这个程序集下所有的相关信息存到assembly对象中,如属性存到对象下的CustomAttributes,类存到对象下的DefinedTypes
Type type = assembly.GetType("hh反射.SqlServerDB");
dynamic oDB = Activator.CreateInstance(type);//创建获得类的对象
MethodInfo method = type.GetMethod("AddRecord");//获得类下的方法
method.Invoke(oDB, new Object[] {1}); //调用方法
- 从上面的代码可以看出,假如全程是用反射来做的话,更换数据库只需要把字符串"hh反射.MySqlDb"变更为"hh反射.SqlServerDB"所以反射可以提供一种不需要修改代码,仅需修改某些配置文件(字符串)就可以改变程序逻辑的功能
四、其他函数
- 判断一个对象是否某个类的对象
Dim text As New TextBox
Dim mObjectT As Type = text.GetType
If mObjectT = GetType(TextBox) Then
Dim kkk = 4
End If
- 在泛型类中,也可以获取泛型类的类型
Private Function huanghaiGetInputClassT_Type() As Type
Return GetType(T)
End Function