反射的用法和好处

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

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

				
时间: 2024-10-10 06:10:24

反射的用法和好处的相关文章

SqlParameter的用法和好处

关于Sql注入的基本概念,相信不需要多说,大家都清楚,经典的注入语句是' or 1=1--单引号而截断字符串,"or 1=1"的永真式的出现使得表的一些信息被暴露出来,如果sql语句是select * from 的话,可能你整个表的信息都会被读取到,更严重的是,如果恶意使用都使用drop命令,那么可能你的整个数据库得全线崩溃.当然,现在重点不是讲sql注入的害处,而是说说如何最大限度的避免注入问题.sql注入的存在在最大危害,是sql的执行语句没有和控制语句分开,我们想要select一

C#SqlParameter的基本用法和好处

今天在看到朋友说起数据库sql注入问题说得比较复杂,就写了一个简单的列子供大家参考: SqlConnection con = new SqlConnection(mySql); //用SqlParameter可以防止Sql注入和一些二进制流的问题(如图片) //SqlParameter sp = new SqlParameter("@username",SqlDbType.VarChar,20); 1:生产名字为@username的参数,2:对应数据库的类型,3:字符串的长度 //sp

Java学习-反射机制入门

1.反射机制 我们在正常的使用过程之中只关心类产生对象,而后通过对象调用类之中的方法,可是,除了这种传统的方式外,也可以利用反射操作. 1.1.认识反射 既然有反,那么一定存在有正,正是指通过类产生对象,而后通过对象执行操作.而反呢?通过对象找到它所在类的信息.所有的对象都支持反这一操作,因为Object类有一个方法:public final Class<?> getClass(). 1 package cn.kvikon.demo; 2 import java.util.Date; 3 4

编程基础知识——C++能不能支持Java和ObjC的反射?

C++能不能支持Java和ObjC的反射? 要回答这个问题,首先我们要清楚什么是反射.什么是反射? 教科书的解释我就不说了,(^o^)其实我也记不得.实际开发应用的反射就是在没有某个类型的头文件或者类结构定义的情况下,存取这个类型的对象的成员字段的值,调用这个对象的成员函数(方法). 比如我有定义了一个类型 Class  A,里面有 a,b,c三个字段,有fun()函数.现在我手里只有一个 void* pA,注意它的类型只是一个void指针,我手里也没有Class的头文件,我要怎么样得到,a,b

MyBATIS插件原理第一篇——技术基础(反射和JDK动态代理)(转)

在介绍MyBATIS插件原理前我们需要先学习一下一些基础的知识,否则我们是很难理解MyBATIS的运行原理和插件原理的. MyBATIS最主要的是反射和动态代理技术,让我们首先先熟悉它们. 1:Java反射技术 在Java中反射技术已经大行其道,通过不断的优化性能得到了巨大的提高,而反射技术使得Java的可配置性大大提高.让我们来写一个服务打印hello + 姓名. import java.lang.reflect.InvocationTargetException; import java.l

Spring IoC的原理为什么是反射而不是new

因为Spring在加载类的实例时,我们知道其实是用工厂的方式,给出一个个实例,而在工厂里面,用了单例,但是真正实例化,则是反射的newInstance来创建对象,而不是new. 那么,为什么是反射的newInstance,而不是new呢? 那么首先我们必须明白,Java里面,反射的目的是什么? 高内聚,低耦合. 进一步,反射比new的好处是什么? 反射不用知道类名,可以直接实例化类,也就是不用硬编码. 有人问了,不知道类名那怎么反射呢? 例子: 通过new,我们这么写: A a = New A(

Html解析

包:jsoup-1.10.2.jar import java.io.File; import java.io.IOException; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.select.Elements; public class TestHtml { public static void main(String[] args) throws IOException { getElem

受康奈尔笔记法启发设计的程序员算法手写本

大多数程序员都习惯了平时在电脑上敲代码,但也有些情境要求我们手写代码,比如平时学习时做纸质笔记,完成老师布置的课程作业,同事之间交流讨论讲解思路,ACM比赛时手写分析算法,还有最常见的面试手写算法等.昨天看了康奈尔笔记法,觉得有点意思,于是想着把它应用到程序员的圈子里来,可以在面试等场合很好的向面试官阐述算法思路同时规范书写,希望能给大家带来一些帮助. 一.什么是康奈尔笔记法 图1.康奈尔笔记法 5R笔记法,又叫做康奈尔笔记法,是用产生这种笔记法的大学校名命名的.这一方法几乎适用于一切讲授或阅读

C#中泛型和单链表

泛型是 2.0 版 C# 语言和公共语言运行库 (CLR) 中的一个新功能.泛型将类型参数的概念引入 .NET Framework,类型参数使得设计如下类和方法成为可能:这些类和方法将一个或多个类型的指定推迟到客户端代码声明并实例化该类或方法的时候.例如,通过使用泛型类型参数 T,您可以编写其他客户端代码能够使用的单个类,而不致引入运行时强制转换或装箱操作的成本或风险 泛型概述:1.使用泛型类型可以最大限度地重用代码.保护类型的安全以及提高性能.2.泛型最常见的用途是创建集合类.3..NET F