NET反射的简单理解与代码示例

来源:互联网 发布:删除表 sql drop 编辑:程序博客网 时间:2024/06/09 15:51

我有一个梦想,是改变世界,这是很多技术人员的梦想;从小事做起,踏实做人做事,当身边的人或事因为自己能像更好的方向改变或发展的时候,那就是在改变世界,至花甲之时,可能我的梦想也无法实现,但我会一直追逐着他前行。我相信蝴蝶效应。荣耀的背后可这一道孤独。一起学习,一起进步。

反射是.NetFrameWork提供给我们的一个帮助类库Reflection.dll
它可以动态加载、解析、使用dll
普通方法我们使用时项目中添加引用,然后实例化使用;

反射基于“元数据”–metadata

Reflection.dll可以读取元数据,然后知道了dll中的方法、属性,则可以调用

以下代码实现了依赖接口,实现可配置、可扩展的动态的加载dll并调用方法(通过接口实现)
比如现在如下的代码实现的是sqlserver的操作,如果我编写了一个Oracle数据库操作的dll继承自IDBHelper,通过配置,那么我就可以实现不变更代码的情况下,实现了通过配置扩展了程序。

配置文件如下:

<add key="DbHelper" value="SqlserverHelperLib.SqlserverHelper,SqlserverHelperLib"/>

代码如下

using System;using System.Configuration;using System.Reflection;using SqlserverHelperLib;namespace Reflaction{    class Program    {        static void Main(string[] args)        {            Console.WriteLine("Reflection的学习");            //--------------原始方法------------------            //引用了SqlserverHelperLib.dll,如果去除了SqlServerHelperLib的引用,那么会导致对象无法创建            var helperOld = new SqlserverHelper();            helperOld.Query(@"old");            Console.WriteLine();            var config = ConfigurationManager.AppSettings["DbHelper"];            var myClass = config.Split(',')[0];            var myNnamspace = config.Split(',')[1];            //动态加载dll            var assembly = Assembly.Load(myNnamspace);            //创建对象            //不用引用SqlserverHelperLib.dll,因为SqlserverHelperLib.dll引用了IDbHelper接口,直接引用接口就行,也能够实现动态加载dll           //基于类的完整名称(命名空间.类名)找出类型            var type = assembly.GetType(myClass);            //根据类型创建对象            var myObj =Activator.CreateInstance(type);            //强制转化为具体类型对象            var helperReflection = (IDbHelperLib.IDbHelper) myObj;            helperReflection.Query("Reflection");            Console.ReadLine();        }    }}

以下代码实现了不依赖接口,实现可配置、可扩展的动态的加载dll
调用普通方法、调用重载方法、调用私有方法、破坏单例

using System;using System.Configuration;using System.Reflection;namespace Reflaction{    class Program    {        static void Main(string[] args)        {            Console.WriteLine("Reflection的学习");            var config = ConfigurationManager.AppSettings["DbHelper"];            var myClass = config.Split(',')[0];            var myNnamspace = config.Split(',')[1];            //动态加载dll            var assembly = Assembly.Load(myNnamspace);            //创建对象            //不用引用SqlserverHelperLib.dll,因为SqlserverHelperLib.dll引用了IDbHelper接口,直接引用接口就行,也能够实现动态加载dll            //基于类的完整名称(命名空间.类名)找出类型            var type = assembly.GetType(myClass);            //根据类型创建对象            var myObj = Activator.CreateInstance(type);            //获取\调用方法            var method = type.GetMethod("Query");            method.Invoke(myObj, new object[] { "不依赖接口Relection" });            //获取\调用重载方法            var method1 = type.GetMethod("Query1", new Type[] { typeof(string) });            method1.Invoke(myObj, new object[] { "不依赖接口Relection1" });            //获取\调用重载方法            var method12 = type.GetMethod("Query1", new Type[] { typeof(int) });            method12.Invoke(myObj, new object[] { 1 });            //获取\调用私有方法            var method2 = type.GetMethod("Query2", BindingFlags.NonPublic|BindingFlags.Public|BindingFlags.Instance);            method2.Invoke(myObj, new object[] { "不依赖接口Relection" });            //使用反射破坏单例--如下代码会实现一次对象的创建,不管你是否时单例,所以破坏了单例(因为单例时不可以创建对象的)            //var myObj = Activator.CreateInstance(type,true);            Console.ReadLine();        }    }}

以下代码实现了基于反射实现的简单数据库访问层
调用类

var helper = new SqlserverHelper();var people = helper.QueryDomain<People>();

数据库操作封装

public T QueryDomain<T>(){    var id = 1;    //获取类型    var type = typeof(T);    //获取该类型对象    var obj = (T)Activator.CreateInstance(type);    foreach (var prop in type.GetProperties())    {        Console.WriteLine("属性名称:{0}", prop.Name);    }    var columns = string.Join(",", type.GetProperties().Select(prop => string.Format("[{0}]", prop.Name)));    string sql = string.Format("SELECT {0} FROM {1} WHERE ID={2}", columns, type.Name, id);    using (var con = new SqlConnection(ConStr))    {         var cmd = new SqlCommand(sql, con);         con.Open();         var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);         if (reader.Read())         {             //获取属性并赋值             foreach (var prop in type.GetProperties())             {                  //获取属性名称                  var propName = prop.Name;                  prop.SetValue(obj, reader[propName], null);                  Console.WriteLine("属性名称:{0},值:{1}", prop.Name, prop.GetValue(obj, null));             }         }    }    return obj;}
原创粉丝点击