Oracle6.C#知识点:反射

1.照是呀?

  反射提供描述组件,模块和种的靶子(类型也Type)。您可以动用反射来动态创建类型的实例,将项目绑定到存活对象,或由现有对象获得项目,并调用其艺术要看该字段和性质。如果你于代码中行使性质,反射而你可看它们。有关重新多信息,请参见属性。—–来自微软官方。

  微软的解说自己以为还得。用大白话讲就是咱们好坐通过反射让咱了解未知类型的音。类似现实生活中之B超啊。医生因此B超看到孕妇肚子里的里边情况,因为医生束手无策从里头查看。反射也是一律,对于不明路。或者引用过来的dll。我们是匪明白其中景象的。但是足以经反射。蝙蝠的超声波也是。通过声波反射回来,得知前方是否生障碍。这即是反射的效用。如果要问反射内部是哪些促成之。不好意思。目前自己吗不了解。哈哈哈哈。

  简单的来说,我们的顺序是由于dll的结缘的,dll里面有巨大底接近组成。类中还要闹字段,属性和办法。反射的企图就让个dll就能够知道有哪类,通过类似以会领略发生哪些成员。那么.net里面的照是怎么好为?那下面将介绍几个类型之反射类了。

   
(1)使用Assembly定义跟加载程序集,加载在先后集清单中列有模块,以及之后程序集中找类型并创办该种的实例。 
   
(2)使用Module了解包含模块的次序集及模块中的类等,还好获在模块上定义的有着全局方法要其他特定的非全局方法。 
   
(3)使用ConstructorInfo了解构造函数的称呼、参数、访问修饰符(如pulic
或private)和贯彻详细信息(如abstract或virtual)等。 
   
(4)使用MethodInfo了解方法的名号、返回路、参数、访问修饰符(如pulic
或private)和促成详细信息(如abstract或virtual)等。
   
(5)使用FiedInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并赢得或设置字段值。
   
(6)使用EventInfo了解事件之名、事件处理程序数据类型、自定义属性、声明类型和反光类型等,添加或移除事件处理程序。 
   
(7)使用PropertyInfo了解属性的称谓、数据类型、声明类型、反射类型及单纯读或可写状态等,获取或安装属性值。 
   
(8)使用ParameterInfo了解参数的称呼、数据类型、是输入参数还是出口参数,以及参数在艺术签名中的职位等。这段话是自大牛的博客拷贝——->传送门

  

脚我逐一重点的介绍几只详细的近乎。

先是是Assembly。这个有于System.Reflection命名空间下面。我重点出口她的3独加载程序集的之办法和区分。Load,LoadForm,LoadFile。

出口了如此多言,先打代码看看语法。

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

namespace 反射Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            //加载程序集
            Assembly assembly = Assembly.Load("TestDLL");

            //输出程序集的强名称
            Console.WriteLine(assembly.FullName);
            Console.ReadKey();
        }
    }
}

Oracle 1

Load方法就是是透过序集的的名目加载程序,但是需要而加载的程序集在眼前程序集的bin目录下才会检索得及。

LoadForm

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

namespace 反射Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            #region Load方法
                    //加载程序集
                   // Assembly assembly = Assembly.Load("TestDLL");

                    //输出程序集的强名称
                    //Console.WriteLine(assembly.FullName);
                    //Console.ReadKey();
            #endregion

            Assembly assmbly1 = Assembly.LoadFrom(@"C:\Users\DH\Documents\visual studio 2017\Projects\反射Demo\TestDLL\bin\Debug\TestDLL.dll");
            Console.WriteLine(assmbly1.FullName);
            Console.ReadKey();
        }
    }
}

LoadForm是通过路径进行创办。返回加载的主次集。

来拘禁最后一个loadFile

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

namespace 反射Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            #region Load方法
            //加载程序集
            // Assembly assembly = Assembly.Load("TestDLL");

            //输出程序集的强名称
            //Console.WriteLine(assembly.FullName);
            //Console.ReadKey();
            #endregion

            #region LoadFrom方法
            //Assembly assmbly1 = Assembly.LoadFrom(@"C:\Users\DH\Documents\visual studio 2017\Projects\反射Demo\TestDLL\bin\Debug\TestDLL.dll");
            //Console.WriteLine(assmbly1.FullName);
            ///Console.ReadKey();
            #endregion

            #region LoadFile方法
            Assembly assmbly2 = Assembly.LoadFile(@"C:\Users\DH\Documents\visual studio 2017\Projects\反射Demo\TestDLL\bin\Debug\TestDLL.dll");
            Console.WriteLine(assmbly2.FullName);
            Console.ReadKey();
            #endregion
        }
    }
}

这三独方法语法都好简单。现在的话说这个三只底界别,和优缺点。

LoadFrom和Load:LoadForm同一个先后集就加载同破,就算加载了不通之门路相同之程序集,他吧不得不为您回之前的程序集,LoadFrom只能用于加载不同标识的程序集,
也不怕是唯一的程序集, 不克用来加载标识相同但路径不同的次序集。 

LoadFile和LoadForm:loadFile只见面加载本身程序集,不会见加在其引用的程序集,LoadForm和Load是会加载的那个引用程序集。而且LoadFile同一个程序集只能加载一糟。这个与LoadForm是一样。

自打性质上看
LoadForm没有Load好,功能上吗是load强一点。应用之时光要loadFom和load都满足需求,建议就此load。

立刻几乎个法子还差点儿单重载版本。由于本片只是基础篇。篇幅不宜过多。想深入了解之小伙伴可以查询MSN看看文档。最详尽的征就是是文档。但是文档说之可比合法。结合大牛们写的博客。更易理解一些。

吓了我们初步下一个级了。程序集现在我们得矣。我开看程序集里面有些什么?

Oracle 2

 

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

namespace 反射Demo
{
    class Program
    {
        static void Main(string[] args)
        {


            #region LoadFrom方法
            Assembly assmbly = Assembly.LoadFrom(@"C:\Users\DH\Documents\visual studio 2017\Projects\反射Demo\TestDLL\bin\Debug\TestDLL.dll");
            Type[] types = assmbly.GetTypes();
            foreach (var item in types)
            {
                Console.WriteLine("类:"+item.Name);

            }
            Console.ReadKey();
            #endregion

        }
    }
}

Oracle 3

assmbly.GetTypes()这个方法或获取了所有类。
下面我我展示下获取字段和方法的字段

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

namespace 反射Demo
{
    class Program
    {
        static void Main(string[] args)
        {


            #region LoadFrom方法
            Assembly assmbly = Assembly.LoadFrom(@"C:\Users\DH\Documents\visual studio 2017\Projects\反射Demo\TestDLL\bin\Debug\TestDLL.dll");
            Type[] types = assmbly.GetTypes();
            foreach (var classitem in types)
            {
                Console.WriteLine("类:"+ classitem.Name);
                foreach (var fileditem in classitem.GetFields())
                {
                    Console.WriteLine("字段名:"+ fileditem.Name);
                }
                foreach (var methodItem in classitem.GetMethods())
                {
                    Console.WriteLine("方法名:"+methodItem.Name);
                }

            }
            Console.ReadKey();
            #endregion

        }
    }
}

 

好拘留的出来我们用字段和章程名都为反射出了,但是发生只问题便是咱们父类的艺术吧给来出来了。我们可改下。这个地方有只重载版本。GetMethods有个重载方法可经BindingFlags枚举参数进行筛选父类的点子,或者其他的。 BindingFlags这个枚举类型。这里虽无多讲。未来我会慢慢补全。

简言之的即使是这般多矣。反射能举行多工作,非常灵活。我们抽象工厂内就会为此到反射。我们的厂子。就是经过反射创建出来。下面我写单demo演示下该作用。

 

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

namespace 反射Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly assmbly = Assembly.Load("TestDLL");
            SqlServerHelper helper =(SqlServerHelper)assmbly.CreateInstance("TestDLL.SqlServerHelper");
            helper.Query();
            Console.ReadKey();
        }
    }
}

同伙等得以发现。我们实例化了一个SqlServerHelper对象,但是咱没有用健康的new方法,而是用了照。这个时候有些小伙伴可能就会见说立刻是排遣裤子放屁,直接new多简单。在此处是是,但是放在确实的类里直接new是当时爽,需求变动就顶在哭吧,比如说以后领导对你说,公司之数据库不用SqlServer了,换成Oracle了。这是时刻要你是new的语还要反这里的代码,实际情形可能重扑朔迷离。但是就此了我们的反射,这种不快就非会见存在了。

CreateInstance(“TestDLL.SqlServerHelper”)
这个方式参数我们全可以由此部署文件修改。这个看似就不需要转移了。我来演示下代码

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

namespace TestDLL
{
    public interface IDBHelper
    {
        void Query();
    }
}

 先创建一个约定数据操作的接口
IDBHlper类。规定来一个Query方法,然后让SqlServerHelper继承这个接口,并且实现之法子。

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

namespace TestDLL
{
    public class SqlServerHelper: IDBHelper
    {
        public void Query()
        {
            Console.WriteLine("这是测试");
        }
    }
}

 然后改mian函数的法门

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <appSettings>
    <add key="Helper" value="TestDLL.SqlServerHelper"/>
  </appSettings>
</configuration>

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using TestDLL;

namespace 反射Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly assmbly = Assembly.Load("TestDLL");
            string helperkey = ConfigurationManager.AppSettings["Helper"];
            IDBHelper helper =(IDBHelper)assmbly.CreateInstance(helperkey);
            helper.Query();
            Console.ReadKey();
        }
    }
}

这时若要用mian函数里面helper切换成Oracle的如果加上一个继续给IDBheper接口的好像,然后实现方式,在修改配置文件对是类似,然后便可了。对于main函数我们是一些不需要动的,这是就是是我们具有的赛内集低耦合。完成解耦。易于修改。

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

namespace TestDLL
{
    public class OracleHelper : IDBHelper
    {
        public void Query()
        {
            Console.WriteLine("我是Orcle数据库");
        }
    }
}

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <appSettings>
    <add key="Helper" value="TestDLL.OracleHelper"/>
  </appSettings>
</configuration>

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using TestDLL;

namespace 反射Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly assmbly = Assembly.Load("TestDLL");
            string helperkey = ConfigurationManager.AppSettings["Helper"];
            IDBHelper helper =(IDBHelper)assmbly.CreateInstance(helperkey);
            helper.Query();
            Console.ReadKey();
        }
    }
}

mian函数或多或少都没变化。运行查看结果

Oracle 4

至了这个里,我就演示了一个反光应用场景了。其实VS本身就是广大地方用了反光。比如。创建对象调用方法上Oracle 5VS直接只能帮助咱列出这个目标下的分子。这个就是经过反射。其实还有许多。等待大家去发现。反射应该属于C#个中的高等知识点了。目前所说之只是是冰山一角。

Ok。讲到此处虽收了哈。

若是正好起上之伴还出问题的语,可以评我们一块儿学学。

若哪位很牛随便瞄Oracle到只错,也呼吁告之我,让自身能够进步。

 

 

相关文章