C#反射实例应用--------获取程序集信息和通过类名创建类实例

时间:2020-11-29 05:31:39

AppDomain.CurrentDomain.GetAssemblies();获取程序集,但是获取的只是已经加载的dll,引用的获取不到。

System.Reflection.Assembly.GetEntryAssembly().GetReferencedAssemblies(); 获取程序集,包括已经加载的和引用的未加载的dll,

但是获取的不是Assembly对象集,而是AssemblyName对象集。,这一点要清楚。。好的话不多说,开始正题哦。

C#反射获取程序集信息和通过类名创建类实例 。

System.Reflection 命名空间:包含通过检查托管代码中程序集、模块、成员、参数和其他实体的元数据来检索其相关信息的类型。

Assembly 类:表示一个程序集,它是一个可重用、无版本冲突并且可自我描述的公共语言运行库应用程序构造块。

注意下面说到的完全限定名是是指 类的完全限定名(命名空间 + 类名)

1、反射获取程序集信息

C#反射实例应用--------获取程序集信息和通过类名创建类实例

1.1 创建AssemblyResult.cs类,用于保存结果

 

  1. /// <summary>  
  2. /// 反射结果类  
  3. /// </summary>  
  4. public class AssemblyResult  
  5. {  
  6.     /// <summary>  
  7.     /// 程序集名称  
  8.     /// </summary>  
  9.     public List<string> AssemblyName { get; set; }  
  10.   
  11.     /// <summary>  
  12.     /// 类名  
  13.     /// </summary>  
  14.     public List<string> ClassName { get; set; }  
  15.   
  16.     /// <summary>  
  17.     /// 类的属性  
  18.     /// </summary>  
  19.     public List<string> Properties { get; set; }  
  20.   
  21.     /// <summary>  
  22.     /// 类的方法  
  23.     /// </summary>  
  24.     public List<string> Methods { get; set; }  
  25. }  

 

1.2 创建AssemblyHandler.cs反射处理类

注意:要引用System.Reflection 命名空间。

 

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Reflection;  
  6. using System.IO;  
  7.   
  8. namespace MyStudyFrom  
  9. {  
  10.     /// <summary>  
  11.     /// 反射处理类  
  12.     /// </summary>  
  13.     public class AssemblyHandler  
  14.  {  
  15.    string path = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @"/he.dll/";  
  16.    /// <summary>  
  17.    /// 获取程序集名称列表  
  18.   /// </summary>  
  19.   public AssemblyResult GetAssemblyName()  
  20.    {  
  21.             AssemblyResult result = new AssemblyResult();  
  22.             string[] dicFileName = Directory.GetFileSystemEntries(path);  
  23.             if(dicFileName!=null)  
  24.             {  
  25.                 List<string> assemblyList = new List<string>();  
  26.                 foreach(string name in dicFileName)  
  27.                 {  
  28.                     assemblyList.Add(name.Substring(name.LastIndexOf('/') + 1));  
  29.                 }  
  30.                 result.AssemblyName = assemblyList;  
  31.             }  
  32.             return result;  
  33.         }  
  34.   
  35.         /// <summary>  
  36.         /// 获取程序集中的类名称  
  37.         /// </summary>  
  38.         /// <param name="assemblyName">程序集</param>  
  39.         public AssemblyResult GetClassName(string assemblyName)  
  40.         {  
  41.             AssemblyResult result = new AssemblyResult();  
  42.             if (!String.IsNullOrEmpty(assemblyName))  
  43.             {  
  44.                 assemblyName = path + assemblyName;  
  45.                 Assembly assembly = Assembly.LoadFrom(assemblyName);  
  46.                 Type[] ts = assembly.GetTypes();  
  47.                 List<string> classList = new List<string>();  
  48.                 foreach (Type t in ts)  
  49.                 {  
  50.                     //classList.Add(t.Name);  
  51.                     classList.Add(t.FullName);  
  52.                 }  
  53.                 result.ClassName = classList;  
  54.             }  
  55.             return result;  
  56.         }  
  57.   
  58.         /// <summary>  
  59.         /// 获取类的属性、方法  
  60.         /// </summary>  
  61.         /// <param name="assemblyName">程序集</param>  
  62.         /// <param name="className">类名</param>  
  63.         public AssemblyResult GetClassInfo(string assemblyName, string className)  
  64.         {  
  65.             AssemblyResult result = new AssemblyResult();  
  66.             if (!String.IsNullOrEmpty(assemblyName) && !String.IsNullOrEmpty(className))  
  67.             {  
  68.                 assemblyName = path + assemblyName;  
  69.                 Assembly assembly = Assembly.LoadFrom(assemblyName);  
  70.                 Type type = assembly.GetType(className,true,true);  
  71.                 if (type != null)  
  72.                 {  
  73.                     //类的属性  
  74.                     List<string> propertieList = new List<string>();  
  75.                     PropertyInfo[] propertyinfo = type.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);  
  76.                     foreach (PropertyInfo p in propertyinfo)  
  77.                     {  
  78.                         propertieList.Add(p.ToString());  
  79.                     }  
  80.                     result.Properties = propertieList;
  81.                     //类的构造函数
  82.                     //1、无参构造函数
  83.                     ConstructorInfo constructor = type .GetConstructor(Type.EmptyTypes);
  84.                     //通过构造函数初始化实例对象,该对象可以用于方法、属性的调用与设置
  85.                     Object constructorObject = constructor.Invoke(new  Object[]{ });
  86.                     //2、有参构造函数
  87.                     ConstructorInfo constructor = type .GetConstructor(Type.EmptyTypes);
  88.                     //具体几个参数,可以在new  Object[]{1 }这里面设置
  89.                     Object constructorObject = constructor.Invoke(new  Object[]{1 });
  90.                     //ConstructorInfo constructor = type .GetConstructor(Type.EmptyTypes);
  91.                     ////通过构造函数初始化实例对象,该对象可以用于方法、属性的调用与设置
  92.                     //Object constructorObject = constructor.Invoke(new  Object[]{ });
  93.                     //类的方法  
  94.                     List<string> methods = new List<string>();  
  95.                     MethodInfo[] methodInfos = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);  
  96.                     foreach (MethodInfo mi in methodInfos)  
  97.                     {  
  98.                         methods.Add(mi.Name);  
  99.                         //方法的参数  
  100.                         //foreach (ParameterInfo p in mi.GetParameters())  
  101.                         //{  
  102.   
  103.                         //}  
  104.                         //方法的返回值  
  105.                         //string returnParameter = mi.ReturnParameter.ToString();  
  106.                     }  
  107.                     result.Methods = methods;  
  108.                 }  
  109.             }  
  110.             return result;  
  111.         }  
  112.     }  
  113. }   

2、通过类名创建类实例 

2.1、假设你要反射一个 DLL 中的类,并且没有引用它(即未知的类型): 
Assembly assembly = Assembly.LoadFile("程序集路径,不能是相对路径"); // 加载程序集(EXE 或 DLL) 
object obj = assembly.CreateInstance("类的完全限定名(即包括命名空间)"); // 创建类的实例 

2.2、若要反射当前项目中的类可以为:

Assembly assembly = Assembly.GetExecutingAssembly(); // 获取当前程序集 

object obj = assembly.CreateInstance("类的完全限定名(即包括命名空间)");

// 创建类的实例,返回为 object 类型,需要强制类型转换

2.3、也可以为:

Type type = Type.GetType("类的完全限定名"); 

object obj = type.Assembly.CreateInstance(type); 

2.4、还可以(建议使用这种方法):

Type type = assembly.GetType();

Object object = System.Activator.CreateInstance(type);//需要转换成对应的控件对象


======================================================= 
补充:
1)反射创建某个类的实例时,必须保证使用类的完全限定名(命名空间 + 类名)。

Type.GetType 方法返回 null 则意味搜索元数据中的相关信息失败(反射失败),请确保反射时使用类的完全限定名。

2)反射功能十分强大,没有什么不能实现的。若实现“跨程序集”,请使用第一种方法创建类的实例,并反射该实例的字段、属性、方法、事件等,然后就可以进行动态的调用它们了。