• c#-反射的使用


    1     /// <summary>
    2     /// 名称:Reflection/反射
    3     /// 场景:有一个dll,通过反射我们来获取信息,并使用
    4     /// </summary>
     1   /// <summary>
     2         /// 反射使用
     3         /// 前提条件:
     4         /// ①我们有一个 dll: language .dll
     5         /// ②language.dll 里面有个 China.cs 类,类里面有个方法SayHi();
     6         /// 目的:获取china.cs,调用SayHi();
     7         /// </summary>
     8         public static void GetClassInfo()
     9         {
    10             //第一步:using System.Reflection;
    11 
    12             //第二步 使用关键字 Assembly 获取dll信息,有三种方法,一般我们使用第一种
    13             Assembly assembly = Assembly.Load("language");       //dll的名称,不加.dll后缀名,这里的意思就是在当前运行文件夹下获取 dll
    14             Assembly assembly2 = Assembly.LoadFile("D:/Refrition/bin/Debug/language.dll");  //dll所在的实际路径
    15             Assembly assembly3 = Assembly.LoadFrom("language.dll");  //dll的全名称
    16 
    17             //获取assembly里面的所有模块信息
    18             foreach (var item in assembly.GetModules())
    19             {
    20                 Console.WriteLine(item.Name);
    21             }
    22 
    23             // 获取assembly里面的所有类型信息
    24             foreach (var item in assembly.GetTypes())
    25             {
    26                 Console.WriteLine(item.Name);
    27             }
    28 
    29             Type type = assembly.GetType("language.China"); //(命名空间+类型名称) | 通过名称获取类型
    30             object oValue = Activator.CreateInstance(type); //通过类型来创建该类型的实例
    31             MethodInfo method = type.GetMethod("SayHi");    //通过方法的名称得到方法
    32             method.Invoke(oValue,null);                     //调用方法(创建的实例,方法的参数)
    33         }

    反射 + 简单工厂+ 可配置/可扩展

    前提条件:建一个类库,我们定义一个接口

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace DataBaseCrud
     8 {
     9     public interface IBaseCrudServer
    10     {
    11         void SayHi();
    12     }
    13 }

      新建一个类库 SqlServer.Server,然后在里面建一个类 sqlServerHelper.cs 然后引用 DataBaseCrudServer 命名空间
     

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 using DataBaseCrud;
     7 
     8 namespace SqlServer.Server
     9 {
    10     public class SqlServerHelper : IBaseCrudServer
    11     {
    12         public void SayHi()
    13         {
    14             Console.WriteLine("Sql server say hi");
    15         }
    16     }
    17 }

    新建一个控制台应用程序,添加引用-》程序集-》System.Configuration,然后新建一个类:ReflexFactory.cs

     这里是将我们知道的信息转到了配置文件里面,同上面一样

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 using System.Reflection;
     7 using System.Configuration;
     8 using DataBaseCrud;
     9 
    10 namespace Reflex
    11 {
    12     /// <summary>
    13     /// 
    14     /// </summary>
    15     public static class ReflexFactory
    16     {
    17         private static string[] strConfig = ConfigurationManager.AppSettings["IDBConfig"].Split(','); //从App.config获取配置文件信息
    18 
    19         private static string strTypeName = strConfig[1];//类型名称
    20 
    21         private static string strDllName = strConfig[0];//dll名称
    22         public static IBaseCrudServer CreateInstance() 
    23         {
    24             Assembly assembly = Assembly.Load(strDllName);
    25             Type type = assembly.GetType(strTypeName);
    26             object oValue = Activator.CreateInstance(type);
    27             return oValue as IBaseCrudServer;
    28         }
    29     }
    30 }

    App.config

    1 <?xml version="1.0" encoding="utf-8" ?>
    2 <configuration>
    3     <startup> 
    4         <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
    5     </startup>
    6   <appSettings>
    7     <add key="IDBConfig" value="SqlServer.Server,SqlServer.Server.SqlServerHelper"/>
    8   </appSettings>
    9 </configuration>


    主程序这里调用

     1 using DataBaseCrud;
     2 using System;
     3 using System.Collections.Generic;
     4 using System.Linq;
     5 using System.Text;
     6 using System.Threading.Tasks;
     7 
     8 namespace Reflex
     9 {
    10     class Program
    11     {
    12         static void Main(string[] args)
    13         {
    14             ReflexFactory.GetInfo();
    15             ReflexFactory.CreateInstance().SayHi();
    16             //ReflexFactory.CreateInstance2();
    17             //Singleton.CreateInstance();
    18             //ReflexFactory.CreateInstance3();
    19             //ReflexFactory.CreateInstance4();
    20             //ReflexFactory.CreateInstance5();
    21             Console.ReadKey();
    22         }
    23     }
    24 }

    创建调用DLL里面的泛型/多构造函数等

     1    /// <summary>
     2         /// Reflection 调用DLL里面的普通类里面的普通类的多个构造函数
     3         /// </summary>
     4         public static void CreateInstance2()
     5         {
     6             Assembly assembly = Assembly.LoadFrom("DataBaseCrud.dll");
     7             Type type = assembly.GetType("DataBaseCrud.TestClass");
     8 
     9             object oValue = Activator.CreateInstance(type, null);
    10             object oValue2 = Activator.CreateInstance(type, new object[] { 123 });
    11             object oValue3 = Activator.CreateInstance(type, new object[] { 123, "News" });
    12         }
    13         /// <summary>
    14         /// Reflection 调用DLL里面的单列
    15         /// </summary>
    16         public static void CreateInstance3()
    17         {
    18             Assembly assembly = Assembly.Load("DataBaseCrud");
    19             Type type = assembly.GetType("DataBaseCrud.Singleton");
    20             object oValue = Activator.CreateInstance(type, true);
    21         }
    22 
    23         /// <summary>
    24         /// Reflection 调用DLL里面的泛型类并创建泛型类的实例
    25         /// </summary>
    26         public static void CreateInstance4()
    27         {
    28             Assembly assembly = Assembly.Load("DataBaseCrud");
    29             Type type = assembly.GetType("DataBaseCrud.GenericTest`3");
    30             Type typeNew = type.MakeGenericType(typeof(int), typeof(string), typeof(int));
    31             object oValue = Activator.CreateInstance(typeNew, new object[] { 123, "564", 654 });
    32         }
    33 
    34         /// <summary>
    35         /// Reflection 调用DLL里面的普通类里面的泛型方法
    36         /// </summary>
    37         public static void CreateInstance5()
    38         {
    39             Assembly assembly = Assembly.Load("DataBaseCrud");
    40             Type type = assembly.GetType("DataBaseCrud.GenericTest2");
    41             object oValue = Activator.CreateInstance(type);
    42             MethodInfo methodInfo = type.GetMethod("Show");
    43             MethodInfo methodInfoNew = methodInfo.MakeGenericMethod(typeof(int), typeof(string), typeof(int));
    44             methodInfoNew.Invoke(oValue, new object[] { 123, "564", 654 });
    45         }

    以上就是我对反射的理解和学习,如有疑问加QQ:443069755

    欢迎来指教和讨论

    2018年3月26日  补充说明

     1         /// <summary>
     2         /// Reflection 调用DLL里面的普通类里面的泛型方法
     3         /// 扩展:使用 dynamic 弱类型来进行简写我们的反射
     4         /// dynamic 运行时才会程序检查,注意使用,有性能损耗(会转成字典的情况,然后遍历检查)
     5         /// </summary>
     6         public static void CreateInstance5()
     7         {
     8             //常规的反射
     9             {
    10                 Assembly assembly = Assembly.Load("DataBaseCrud");
    11                 Type type = assembly.GetType("DataBaseCrud.GenericTest2");
    12                 object oValue = Activator.CreateInstance(type);
    13                 MethodInfo methodInfo = type.GetMethod("Show");
    14                 MethodInfo methodInfoNew = methodInfo.MakeGenericMethod(typeof(int), typeof(string), typeof(int));
    15                 methodInfoNew.Invoke(oValue, new object[] { 123, "564", 654 });
    16             }
    17             //使用 dynamic 来放便我们简写
    18             {
    19                 Assembly assembly = Assembly.Load("DataBaseCrud");
    20                 Type type = assembly.GetType("DataBaseCrud.GenericTest2");
    21                 dynamic _dynamic = Activator.CreateInstance(type);
    22                 _dynamic.Show(123, "567", 654);
    23             }
    24 
    25         }
  • 相关阅读:
    [Leetcode] Symmetric tree 对称二叉树
    [Leetcode] Populating next right pointer in each node ii 填充每个节点的右指针
    [Leetcode] Populating next right pointer in each node 填充每个节点的右指针
    [Leetcode] Same tree判断是否为相同树
    [Leetcode] Path Sum II路径和
    [Leetcode] Path Sum路径和
    [Leetcode] Binary tree maximum path sum求二叉树最大路径和
    [Leetcode] The minimum depth of binary tree二叉树的最小深度
    设计模式-工厂方法模式
    设计模式-简单工厂模式
  • 原文地址:https://www.cnblogs.com/gcrmmh2/p/8646833.html
Copyright © 2020-2023  润新知