.NET 反射,是指在程序运行时,对于任何一个类,都能够动态地获取该类的所有成员和成员类型,实现对于类、方法、属性、字段等的分析和操作。与编译时确定的静态类型不同,反射提供了一种很灵活的方法去探测并使用类型。
反射主要提供以下几种功能:
1. 能够获取类型的所有成员,包括方法、属性、事件、字段、构造函数等。
2. 能够获取类型的元数据,包括类的基类、实现的接口、类的属性、字段、方法等元数据信息。
3. 能够动态地创建对象、调用方法、设置属性等。
4. 能够在运行时动态地加载程序集。
使用反射需要使用 System.Reflection 命名空间。在使用前需要添加该命名空间的引用,否则编译会出现错误。
下面是使用反射的基本步骤:
1. 加载程序集 Assembly,可以使用 Assembly.Load 或者 Assembly.GetExecutingAssembly 方法加载程序集。
2. 获取类型 Type,可以使用 Assembly.GetType 或者 obj.GetType 获取类型。
3. 使用 Type 类的方法和属性操作类型。
在反射中,最常用的类型是 Type 类型。Type 是所有类型的基类,它描述了一个类型的元数据信息。
获取 Type 的方式有以下几种:
1. 使用 GetType() 方法。例如:Type type = obj.GetType(); 这里 obj 是一个已经创建好的对象。
2. 直接使用某一个已知类型的 Type。例如:Type type = typeof(string); 这里获取字符串类型的 Type。
3. 使用 Assembly 类的 GetType 方法获取某一个指定程序集内的类型。例如:Type type = Assembly.LoadFile(filePath).GetType("Namespace.ClassName");
反射可以获取类型的各种信息,包括构造函数、属性、字段、方法等等。下面分别介绍各种成员获取的方法和用法。
构造函数:
反射可以获取类型的构造函数,包括无参构造函数、有参构造函数或私有构造函数。获取构造函数可以使用 Type 类的 GetConstructor 方法,示例如下:
```cs
Type type = typeof(Student);
ConstructorInfo constructorInfo = type.GetConstructor(new Type[] { typeof(string), typeof(int) });
```
这里获取 Student 类的带两个参数的构造函数。
属性:
反射可以获取类型的所有属性,包括公有属性、私有属性、只读属性、可写属性等。获取属性可以使用 Type 类的 GetProperty 方法,示例如下:
```cs
Type type = typeof(Student);
PropertyInfo propertyInfo = type.GetProperty("Name");
```
这里获取 Student 类的 Name 属性。
字段:
反射可以获取类型的所有字段,包括公有字段、私有字段等。获取字段可以使用 Type 类的 GetField 方法,示例如下:
```cs
Type type = typeof(Student);
FieldInfo fieldInfo = type.GetField("age");
```
这里获取 Student 类的 age 字段。
方法:
反射可以获取类型的所有方法,包括公有方法、私有方法、静态方法等。获取方法可以使用 Type 类的 GetMethod 方法,示例如下:
```cs
Type type = typeof(Student);
MethodInfo methodInfo = type.GetMethod("SayHello");
```
这里获取 Student 类的 SayHello 方法。
除了获取类型的各种成员之外,反射还可以用来创建实例、调用方法、设置属性、调用私有方法等。下面分别介绍各种用法。
创建实例:
反射可以动态地创建某一个类型的对象。获取类型 Type 后,可以使用 Activator.CreateInstance 方法动态创建对象,示例如下:
```cs
Type type = typeof(Student);
object obj = Activator.CreateInstance(type);
```
这里创建了 Student 类的对象。
调用方法:
反射可以动态地调用某一个类型的方法。获取类型 Type 后,可以使用 MethodInfo.Invoke 方法动态调用方法,示例如下:
```cs
Type type = typeof(Student);
object obj = Activator.CreateInstance(type);
MethodInfo methodInfo = type.GetMethod("SayHello");
methodInfo.Invoke(obj, null);
```
这里调用 Student 类的 SayHello 方法。
设置属性:
反射可以动态地设置某一个类型的属性。获取类型 Type 后,可以使用 PropertyInfo.SetValue 方法动态设置属性的值,示例如下:
```cs
Type type = typeof(Student);
object obj = Activator.CreateInstance(type);
PropertyInfo propertyInfo = type.GetProperty("Name");
propertyInfo.SetValue(obj, "张三", null);
```
这里设置 Student 类的 Name 属性为“张三”。
调用私有方法:
反射可以动态地调用某一个类型的私有方法。获取类型 Type 后,可以使用 MethodInfo 实例的 SetAccessible 方法将私有方法变为可访问的,然后再调用 Invoke 方法动态调用私有方法,示例如下:
```cs
Type type = typeof(Student);
object obj = Activator.CreateInstance(type);
MethodInfo method = type.GetMethod("SaySomething", BindingFlags.Instance | BindingFlags.NonPublic);
method.SetAccessible(true);
object result = method.Invoke(obj, new object[] { "Hello World" });
```
这里调用 Student 类的私有方法 SaySomething,传入参数“Hello World”。
使用反射可以实现灵活的程序设计,但同时也存在着性能方面的问题。因为反射在运行时动态获取类型和调用成员,所以比静态编译的代码要慢很多。因此,在使用反射时需要权衡灵活性和性能之间的平衡。 如果你喜欢我们三七知识分享网站的文章, 欢迎您分享或收藏知识分享网站文章 欢迎您到我们的网站逛逛喔!https://www.37seo.cn/
发表评论 取消回复