反射的用法和好处

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反射的用法和好处相关的知识,希望对你有一定的参考价值。

今天我们就来说一说反射(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)使用反射会模糊程序内内部逻辑:程序员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂。

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


 


以上是关于反射的用法和好处的主要内容,如果未能解决你的问题,请参考以下文章

java 反射代码片段

大数据必学Java基础(八十八):通过案例和概念体会反射的好处

反射的好处

OpenGL片段着色器不照亮场景

Java核心技术梳理-类加载机制与反射

c_cpp 加载源图像固定用法(代码片段,不全)