反射的用法和好处

时间:2021-11-22 15:54:08

今天我们就来说一说反射(Reflection ),

反射是什么呢?反射是动态获取程序集的元数据(metadata)的一种技术。反射是.NetFramework类库提供的帮助类,动态加载dll实现程序的可配置可扩展。

首先我们来看一个简单的实现反射的例子,我们先创建整个框架

反射的用法和好处

IDAL里面是一个接口,接口里面有一个Query方法,

using System;
namespace Reflect.IDAL
{
public interface IHelper
{
void Query();
}
}

  假设这个Query方法就是链接数据库的某个方法,下面我们就实现它

现在有一个sqlserver数据库,我们要写DAL数据Helper类来实现

using Reflect.IDAL;
using System;


namespace Reflect.DAL
{
public class SqlServerHelper : IHelper
{
public SqlServerHelper()
{
Console.WriteLine("这是SqlHelper的构造函数");
}

public void Query()
{
//throw new NotImplementedException();
Console.WriteLine("这是一个假的实现sqlhelp的方法");
}
}
}

  假设我们现在链接了数据库,然后我们就需要在控制台输出一下,在控制台实现之前,我们就要配置一下,反射就是为了实现可配置的嘛。

打开app.Config 添加appSetting节点如下

<appSettings>
<!--<add key="DAL" value="Reflect.DAL,Reflect.DAL.SqlServerHelper"/>-->
<add key="DAL" value="Reflect.MySql.DAL,Reflect.MySql.DAL.MySqlHelper"/>
</appSettings>

  这里有两个key,第一个是sqlServer链接的配置,第二个是MySql的链接配置,sqlServer的配置被注释了,我们实现的也就是mysql的配置,mysql的DAL的代码和sqlServer的类似。

using Reflect.IDAL;
using System;

namespace Reflect.MySql.DAL
{
public class MySqlHelper : IHelper
{
public MySqlHelper()
{
Console.WriteLine("这是MySqlHelper的构造函数");
}

public void Query()
{
Console.WriteLine("这是一个假的实现MySqlHelper的方法");
}
}
}

  这个也就是反射的已扩展,当所有的类定义好以后需要扩展不需要修改实现的代码,下面就是控制台的代码

using Reflect.DAL;
using Reflect.IDAL;
using System;
using System.Configuration;
using System.Reflection;

namespace Reflection
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("****************从这里开始反射*************");
//SqlServerHelper sqlhelper = new SqlServerHelper();
//sqlhelper.Query();

string HelperConfig = ConfigurationManager.AppSettings["DAL"].ToString();
Assembly assenbly = Assembly.Load(HelperConfig.Split(',')[0]);//动态的加载dll
Type typeHelper = assenbly.GetType(HelperConfig.Split(',')[1]);//找出具体的类型

object oHelper = Activator.CreateInstance(typeHelper);//创建对象等同于new

IHelper ihelper = (IHelper)oHelper;//将object类型转换为接口类型
ihelper.Query();

Console.ReadKey();
}
}
}
//SqlServerHelper sqlhelper = new SqlServerHelper();
//sqlhelper.Query();
这里被注释的两行代码其实也能实现,而且是我们平常实现的常用做法,可是他的局限性就是在扩展方面需要修改代码,而我们在编写程序的时候所要求的是对扩展开放,对修改密封,这里他就不太好用了。
当上面所有的实现之后,我们运行程序

反射的用法和好处

我们要是想要更换数据库,只要修改配置文件,不需要修改代码就能实现,是不是好了很多。

<appSettings>
<add key="DAL" value="Reflect.DAL,Reflect.DAL.SqlServerHelper"/>
<!--<add key="DAL" value="Reflect.MySql.DAL,Reflect.MySql.DAL.MySqlHelper"/>-->
</appSettings>

反射的用法和好处

使用反射的优缺点优点:

优点:反射提高了程序的灵活性和扩展性,降低耦合性,提高自适应能力。它允许程序创建和控制任何类的对象,无需提前硬编码目标类;

缺点:(1)性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和扩展性要求很高的系统框架上,普通程序不建议使用。

   (2)使用反射会模糊程序内内部逻辑:程序员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂。

我们需要在使用反射的时候一定要明确反射的有缺点,这样才能让程序更加完善。