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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sunshineyang1205/article/details/78870416

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

反射是.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;
}

猜你喜欢

转载自blog.csdn.net/sunshineyang1205/article/details/78870416