C# 使用反射遍历对象属性及值
在 C# 开发中,有时需要在不知道具体类型定义的情况下读取对象的字段或属性值。利用反射(Reflection)可以动态地获取运行时的元数据。本文将演示如何遍历一个对象实例的所有可访问属性,并提取其名称与当前值。
核心原理
反射遍历对象属性的核心在于获取 Type 对象,并通过该对象查询其包含的 PropertyInfo 集合。只有同时拥有公开的 get 和 set 访问器的属性才能被正常读写和识别,这是进行此类操作的前提条件。
操作步骤
第 1 步:获取对象的 Type 信息
首先需要从具体的对象实例中提取出其对应的类型元数据。这一步是后续所有反射操作的基础入口。
- 目的:锁定当前变量所属的类结构。
- 动作:调用实例的
GetType()方法。
object tc = new YourClass(); // 假设这是你的目标对象
Type t = tc.GetType(); // 获得该类的 Type
第 2 步:获取所有公共属性列表
基于已获取的 Type 对象,查询当前类定义的公共属性。这将返回一个 PropertyInfo[] 数组,其中每个元素代表一个属性描述符。
- 目的:收集当前对象下所有符合规则的属性名。
- 入口:
System.Type的GetProperties()方法。 - 参数:默认情况下获取所有公共属性(Public)。若需包括非公共属性,需传入相应的 BindingFlags。
第 3 步:遍历属性并提取值
使用 foreach 循环遍历属性数组,逐个提取属性名称和当前存储的值。同时可以根据需要进行类型判断以执行特定逻辑。
- 目的:将静态的类型结构转化为具体的运行时数据。
- 动作:遍历
PropertyInfo数组,调用GetValue()和Name属性。 - 关键代码:
-pi.Name:获取属性的字符串名称。
-pi.GetValue(tc, null):获取指定对象在该属性上的值。第二个参数为索引器偏移量,非索引属性通常传null。
-value.GetType():判断值的实际类型,以便后续处理。
//再用 Type.GetProperties 获得 PropertyInfo[],然后就可以用 foreach 遍历了
foreach (PropertyInfo pi in t.GetProperties())
{
object value1 = pi.GetValue(tc, null); // 用 GetValue 获得值
string name = pi.Name; // 获得属性的名字
// 获得属性的类型,进行判断然后进行以后的操作
// 例如:判断获得的属性是否为整数类型
if (value1 != null && value1.GetType() == typeof(int))
{
// 这里可以写入针对整型属性的特定逻辑
Console.WriteLine($"{name} is an int with value: {value1}");
}
}
注意事项与排错
必须设置 get 和 set 方法
为了确保反射能够成功读取和操作,类中的属性必须具备公开的 getter 和 setter。如果属性缺少其中之一,在某些反射行为中可能不会被预期地枚举出来,或者在尝试赋值时抛出异常。
以下是一个标准的符合反射遍历要求的属性定义:
public int Pid
{
get { return pid; } // 必须有公开 get
set { pid = value; } // 必须有公开 set
}
空值处理
在实际项目中,某些属性可能值为 null(如引用类型或 Nullable 类型)。直接调用 .GetType() 会对 null 引发 NullReferenceException。因此,在判断类型前务必增加 value1 != null 的检查。
性能考量
反射是一种耗时的操作,特别是在高频调用的场景(如 Web 请求循环)中,可能会显著降低应用性能。如果需要高性能的数据映射,建议考虑使用表达式树编译委托或专门的库(如 System.Text.Json 的序列化机制),而非在运行时频繁使用裸反射。
总结
通过组合使用 GetType()、GetProperties() 以及 GetValue(),你可以灵活地在 C# 中以编程方式探查任何对象的内部状态。这对于编写通用的工具类、调试工具以及自动化测试非常有用。请始终确保目标属性具有完整的访问器定义,并在处理值之前做好非空检查。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













