反射

一、课前准备

现在有三个类,分别是:

  1. 接口

interface DBHelper

{

void AddRecord(int i);

}

  1. 实现接口类1 MySqlDb

    class MySqlDb : DBHelper

    {

    public void AddRecord(int i)

    {

    Console.WriteLine("这里使用的是MySql数据库新增一条记录");

    }

    }

  2. 实现接口类2 SqlServerDB

    class SqlServerDB : DBHelper

    {

    public void AddRecord(int i)

    {

    Console.WriteLine("这里使用的是SqlServer数据库新增一条记录");

    }

    }

    二、反射引入

  3. 普通定义并使用对象

    DBHelper hhDB = new MySqlDb();

    hhDB.AddRecord();

  4. 利用反射定义并使用对象方法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}); //调用方法

    1.  
    2. 其中程序集名称是:

  5. 利用反射定义并使用对象方法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}); //调用方法

  6. 利用反射定义并使用对象方法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}); //调用方法

  7. 反射构造函数

       

        Dim DllPath As String = My.Application.Info.DirectoryPath & "\Oracle.ManagedDataAccess.dll"
        If IO.File.Exists(DllPath) = False Then
            MsgBox("Oracle.ManagedDataAccess.dll 不存在!")
        End If
        Dim OracleConType As Assembly = Assembly.LoadFile(DllPath)
        Dim mtype As Type = OracleConType.GetType("Oracle.ManagedDataAccess.Client.OracleConnection")
        Dim hhOracleCon As Object = Activator.CreateInstance(mtype)

        Dim OracleCmdType As Type = OracleConType.GetType("Oracle.ManagedDataAccess.Client.OracleCommand")
        Dim OracleCMD As Object = hhOracleCon.CreateCommand
        '获取所有构造函数
        Dim constructors As ConstructorInfo() = OracleCmdType.GetConstructors()
        '遍历所有构造函数
        For Each item As ConstructorInfo In constructors
            Dim paramsInfos As ParameterInfo() = item.GetParameters() '获取构造函数的参数信息
            If paramsInfos.Length = 2 Then '取得只有两个参数的构造函数
                Dim o As List(Of Object) = New List(Of Object)() From {"1", hhOracleCon}
                OracleCMD = constructors(2).Invoke(o.ToArray()) '传入参数调用构造函数
            End If
        Next
        OracleCMD.ExecuteNonQuery()

 

 

 

 

 

  1. 三、反射基本应用

接口:DBHelper

实现类1:MySqlDb

实现类2:SqlServerDB

上述的三个类,MySqlDbSqlServerDB都是继承与接口DBHelper,即实现类不直接依赖细节而是依赖抽象(接口),即下面使用的对象都是定义为抽象(接口)DBHelper类型的,这样的好处就是只要抽象(接口)不变,我上层的代码就不需要改变。假如实际项目中需要把数据库MySqlDb改为SqlServerDB数据库可以通过下面实现:

  1. 假如项目中本来是应用MySqlDb

DBHelper hhDB = new MySqlDb();

hhDB.AddRecord();

  1. 现改为SqlServerDB

    DBHelper hhDB = new SqlServerDB ();

hhDB.AddRecord();

  1. 上面只对New后的类型修改即可,仍然是需要修改代码,假如项目中一开始就是利用反射来调用数据库。那么需要这样修改:
  2. 反射调用时本来是应用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}); //调用方法

  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}); //调用方法

  1. 从上面的代码可以看出,假如全程是用反射来做的话,更换数据库只需要把字符串"hh反射.MySqlDb"变更为"hh反射.SqlServerDB"所以反射可以提供一种不需要修改代码,仅需修改某些配置文件(字符串)就可以改变程序逻辑的功能

 

posted @ 2022-04-30 19:05  ihh2021  阅读(78)  评论(0编辑  收藏  举报