通常,反射用于动态获取对象的类型、属性和方法等信息。今天带你玩转反射,来汇总一下反射的各种常见操作,捡漏看看有没有你不知道的。
获取类型的成员
Type 类的 GetMembers 方法用来获取该类型的所有成员,包括方法和属性,可通过 BindingFlags 标志来筛选这些成员。
using System;using System.Reflection;using System.Linq;public class Program
{
public static voidMain()
{
var members = typeof(object).GetMembers(BindingFlags.Public |
BindingFlags.Static | BindingFlags.Instance);foreach (var member in members)
{
Console.WriteLine($"{member.Name} is a {member.MemberType}");
}
}
}
输出:
GetType is a Method
GetHashCode is a Method
ToString is a Method
Equals is a Method
ReferenceEquals is a Method
.ctor is a Constructor
GetMembers 方法也可以不传 BindingFlags,默认返回的是所有公开的成员。
获取并调用对象的方法
Type 类型的 GetMethod 方法用来获取该类型的 MethodInfo,然后可通过 MethodInfo 动态调用该方法。
对于非静态方法,需要传递对应的实例作为参数,示例:
class Program
{
public static void Main()
{
var str = "hello";var method = str.GetType()
.GetMethod("Substring", new[] {
typeof(int), typeof(int)});var result = method.Invoke(str, new object[] {
0, 4}); // 相当于 str.Substring(0, 4)
Console.WriteLine(result); // 输出:hell
}
}
对于静态方法,则对象参数传空,示例:
var method = typeof(Math).GetMethod("Exp");// 相当于 Math.Exp(2)var result = method.Invoke(null, new object[] {
2});
Console.WriteLine(result); // 输出(e^2):7.38905609893065
如果是泛型方法,则还需要通过泛型参数来创建泛型方法,示例:
class Program
{
public static void Main()
{
// 反射调用泛型方法
MethodInfo method1 = typeof(Sample).GetMethod("GenericMethod");
MethodInfo generic1 = method1.MakeGenericMethod(typeof(string));
generic1.Invoke(sample, null);// 反射调用静态泛型方法
MethodInfo method2 = typeof(Sample).GetMethod("StaticMethod");
MethodInfo generic2 = method2.MakeGenericMethod(typeof(string));
generic2.Invok