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

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

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

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

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

1、反射获取程序集信息

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

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

/// <summary>
/// 反射结果类
/// </summary>
public class AssemblyResult
{
/// <summary>
/// 程序集名称
/// </summary>
public List<string> AssemblyName { get; set; }

/// <summary>
/// 类名
/// </summary>
public List<string> ClassName { get; set; }

/// <summary>
/// 类的属性
/// </summary>
public List<string> Properties { get; set; }

/// <summary>
/// 类的方法
/// </summary>
public List<string> Methods { get; set; }
}

1.2 创建AssemblyHandler.cs反射处理类

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.IO;

namespace MyStudyFrom
{
/// <summary>
/// 反射处理类
/// </summary>
public class AssemblyHandler
{
string path = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @"/MyDLL/";

/// <summary>
/// 获取程序集名称列表
/// </summary>
public AssemblyResult GetAssemblyName()
{
AssemblyResult result = new AssemblyResult();
string[] dicFileName = Directory.GetFileSystemEntries(path);
if(dicFileName!=null)
{
List<string> assemblyList = new List<string>();
foreach(string name in dicFileName)
{
assemblyList.Add(name.Substring(name.LastIndexOf('/') + 1));
}
result.AssemblyName = assemblyList;
}
return result;
}

/// <summary>
/// 获取程序集中的类名称
/// </summary>
/// <param name="assemblyName">程序集</param>
public AssemblyResult GetClassName(string assemblyName)
{
AssemblyResult result = new AssemblyResult();
if (!String.IsNullOrEmpty(assemblyName))
{
assemblyName = path + assemblyName;
Assembly assembly = Assembly.LoadFrom(assemblyName);
Type[] ts = assembly.GetTypes();
List<string> classList = new List<string>();
foreach (Type t in ts)
{
//classList.Add(t.Name);
classList.Add(t.FullName);
}
result.ClassName = classList;
}
return result;
}

/// <summary>
/// 获取类的属性、方法
/// </summary>
/// <param name="assemblyName">程序集</param>
/// <param name="className">类名</param>
public AssemblyResult GetClassInfo(string assemblyName, string className)
{
AssemblyResult result = new AssemblyResult();
if (!String.IsNullOrEmpty(assemblyName) && !String.IsNullOrEmpty(className))
{
assemblyName = path + assemblyName;
Assembly assembly = Assembly.LoadFrom(assemblyName);
Type type = assembly.GetType(className,true,true);
if (type != null)
{
//类的属性
List<string> propertieList = new List<string>();
PropertyInfo[] propertyinfo = type.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
foreach (PropertyInfo p in propertyinfo)
{
propertieList.Add(p.ToString());
}
result.Properties = propertieList;

//类的方法
List<string> methods = new List<string>();
MethodInfo[] methodInfos = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (MethodInfo mi in methodInfos)
{
methods.Add(mi.Name);
//方法的参数
//foreach (ParameterInfo p in mi.GetParameters())
//{

//}
//方法的返回值
//string returnParameter = mi.ReturnParameter.ToString();
}
result.Methods = methods;
}
}
return result;
}
}
}

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);

=======================================================
补充:
1)反射创建某个类的实例时,必须保证使用类的完全限定名(命名空间 + 类名)。Type.GetType 方法返回 null 则意味搜索元数据中的相关信息失败(反射失败),请确保反射时使用类的完全限定名。
2)反射功能十分强大,没有什么不能实现的。若实现“跨程序集”,请使用第一种方法创建类的实例,并反射该实例的字段、属性、方法、事件... 然后动态调用之。