开发中在设计动态调用时,就需要用到C#的反射,使用反射可以利用程序集、类型等动态的创建相应的实例,调用其中的方法或访问字段和属性等操作。
加载程序集使用Assembly类:
Assembly assembly = Assembly.Load("System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e");
加载类型使用Type类:
Type type = typeof(ReflectionTest);
加载方法使用MethodInfo类:
MethodInfo method = type.GetMethod("WriteTest");
加载属性使用PropertyInfo类:
PropertyInfo property = assembly.GetType("System.DateTime").GetProperty("Now");
加载构造函数使用ConstructorInfo类:
ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes);
参考代码:
class ReflectionDemo
{
public static void DemoMain()
{
Type type = typeof(ReflectionTest);
Console.WriteLine("-----获取所有公开的属性-----");
foreach (var item in type.GetProperties())
{
Console.WriteLine(item.Name);
}
Console.WriteLine("-----获取所有公开的字段-----");
foreach (var item in type.GetFields())
{
Console.WriteLine(item.Name);
}
Console.WriteLine("-----获取所有公开的成员-----");
foreach (var item in type.GetMembers())
{
Console.WriteLine(item.Name);
}
Console.WriteLine("-----获取所有公开的方法及其参数(如果有)-----");
foreach (var item in type.GetMethods())
{
Console.WriteLine($"{item.Name},{string.Join(',', item.GetParameters().ToList())}");
}
Console.WriteLine("-----获取所有私有的方法及其参数(如果有)和返回值类型-----");
foreach (var item in type.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly))
{
Console.WriteLine($"{item.Name},参数:{string.Join(',', item.GetParameters().ToList())},返回值:{item.ReturnType}");
}
Console.WriteLine("-----获取所有公开的构造函数及其参数(如果有)-----");
foreach (var item in type.GetConstructors())
{
Console.WriteLine($"{item.Name},{string.Join(',', item.GetParameters().ToList())}");
}
//获取无参构造函数
ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes);
//通过构造函数创建实例
object obj = constructor.Invoke(null);
//通过反射调用
MethodInfo method = type.GetMethod("WriteTest");
method.Invoke(obj, null);
//构造参数类型数组
Type[] types = new Type[2];
types[0] = typeof(string);
types[1] = typeof(int);
//构造参数数组
object[] parameters = new object[2];
parameters[0] = "aaa";
parameters[1] = 1999;
//获取有参构造函数
ConstructorInfo constructor1 = type.GetConstructor(types);
//通过有参构造函数创建实例
object obj1 = constructor1.Invoke(parameters);
//调用重写的ToString方法确认参数已传递至字段
MethodInfo method1 = type.GetMethod("ToString");
object result = method1.Invoke(obj1, null);
Console.WriteLine($"重写的ToString方法返回结果:{result}");
//调用私有方法
MethodInfo method2 = type.GetMethod("GetStr", BindingFlags.Instance | BindingFlags.NonPublic);
object result1 = method2.Invoke(obj1, null);
Console.WriteLine($"私有GetStr方法返回结果:{result1}");
Assembly assembly = Assembly.Load("System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e");
object datetime = assembly.CreateInstance("System.DateTime");
PropertyInfo property = assembly.GetType("System.DateTime").GetProperty("Now");
object time =property.GetValue(datetime);
Console.WriteLine($"通过反射获取当前时间:{time}");
}
}
class ReflectionTest
{
public string Test1;
public int Test2;
private string Test3;
private int Test4;
public string Test5 { get; set; }
public ReflectionTest()
{
}
public ReflectionTest(string t1, int t2)
{
this.Test1 = t1;
this.Test2 = t2;
}
public void WriteTest()
{
Console.WriteLine("WriteTest方法输出");
}
private string GetStr()
{
return "私有成员GetStr返回";
}
public override string ToString()
{
return $"Test1={Test1},Test2={Test2},Test3={Test3},Test4={Test4}";
}
}
输出结果: