首页 > 代码库 > 反射学习由浅入深

反射学习由浅入深

第一,引入:dll的引入方法  通过当前控制台应用程序的引用的添加(解决方案下的引用)     再到命名空间的引用(使用类中的引用)

首先,在解决方案下新建一个类库及一个控制台应用程序(类库可编辑成dll文件)【注类库与应用程序在同一解决方案同级下】

技术分享

 

控制台应用程序代码为:

using myFeflectionDal.Dal;//SqlServerHelper命名空间的引用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace myReflection
{
    class Program
    {
        static void Main(string[] args)
        {
            //普通做法  创建对象的方法
            SqlServerHelper ss = new SqlServerHelper();
            ss.Query();
        }
    }
}

 

类库代码为:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace myFeflectionDal.Dal
{
    //public class SqlServerHelper:IHelper 定义接口后的类写法(接口在下面)
public class SqlServerHelper {
public SqlServerHelper() { Console.WriteLine("这里开始SqlServerHelper构造函数"); } public void Query() { Console.WriteLine("SqlServerHelper Query"); Console.ReadKey(); } } }

 

执行的顺序为:先执行构造函数再在执行普通方法。输出结果的顺序为:先:这里开始SqlServerHelper构造函数     后: SqlServerHelper Query

通过对象掉用。

   第二,通过反射动态加载dll文件  使用类中:使用命名空间  using System.Reflection

      反射就是通过某种事物去反射另一种事物;我们小时候进行喜欢用镜子对着墙上照,会出现一个个小光圈,这就是很典型的反射例子,我们把它理解成计算机里的反射就是我用某中对象去反射我无法直接获取到的东西。

技术分享

     控制台应用程序中的代码:  注意:编译后需将所需的dll文件复制到当前项目的bin目录下然后调用,而不需要在解决方案下引用

1.得到名称

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection; //反射核心命名空间

namespace myReflection
{
    /// <summary>
/// (元数据)metadata+中间语言   =编译后
/// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            
          Assembly assembly= Assembly.Load("myFeflectionDal.Dal");//动态加载dll文件  动态解析 动态使用
           Module[] modules = assembly.GetModules();//GetModules() 获取作为此程序集的一部分的所有模块。
       
foreach (Module module in modules) { Console.WriteLine(module.Name); } } } }
//功能为:打印当前dll文件的名称 模块的

打印结果为:myFeflectionDal.Dal.dll

获取产生dll文件的类型(dll来源)

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using myReflection.Interface;

namespace myReflection
{
    /// <summary>
   /// (元数据)metadata+中间语言   =编译后
   /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            
          Assembly assembly= Assembly.Load("myFeflectionDal.Dal");//动态加载dll文件
            
            Console.WriteLine("----------dll文件产生的类型(来源)--------------------------");

            Type[] types = assembly.GetTypes();//dll里面所有类型

            foreach (Type type in types)
            {
                Console.WriteLine(type.Name);//打印dll的类型
            }
            Type typeHelper = assembly.GetType("myFeflectionDal.Dal.SqlServerHelper");//带命名空间
             object oHelper=   Activator.CreateInstance(typeHelper);
            //此时无法调用SqlServerHelper类里面的方法 所以考虑将SqlServerHelper类里面的方法抽象成接口
            IHelper iHerper = (IHelper)oHelper;
            iHerper.Query();
        }
    }
}

 

IHelper接口定义:

using System;

namespace myReflection.Interface
{
    public interface IHelper
    {
        void Query();
    }
}

总结:普通的通过创建对象 的方式来调用方法(Query) 调用了构造函数,使用反射的方式来创建的对象也同样调用了构造函数。但是此时创建的对象是object  类型,无法去调用SqlServerHelper 类下面的Query方法,需要将SqlServerHelper 类下面的Query方法抽象成接口,然后SqlServerHelper类继承础接口,之后将object类型强转成接口类型,最终就可以通过接口类型去调用方法。

普通对象创建new《=》反射:(1)Module()+(2)Type()+ 【object oHelper=   Activator.CreateInstance(typeHelper);】两个过程都调用构造函数创建了对象,但是类型不一样。

 

反射学习由浅入深