如何在C#中高效遍历类以检测传感器状态异常
问题描述
我在C#中定义了多个类,包含lidar、imu、camera1至camera4等传感器类,需要遍历这些类获取状态值,当传感器状态不为good时输出类似lidar not good的提示。我想到两种实现思路:
- 使用类列表,但不清楚对应的类型应如何设置;
- 通过Root类访问其他类,类似遍历类属性的方式实现,但不知具体操作方法。
初始类结构
public class Battery { public string status { get; set; } public string value { get; set; } } public class Camera1 { public string status { get; set; } } public class Camera2 { public string status { get; set; } } public class Camera3 { public string status { get; set; } } public class Camera4 { public string status { get; set; } } public class Cpu { public string status { get; set; } public string value { get; set; } public string temperature { get; set; } public string ram { get; set; } public string utilisation { get; set; } } public class CurrentJob { public object job { get; set; } public object task { get; set; } public object location { get; set; } } public class Dex { public CurrentJob current_job { get; set; } public Battery battery { get; set; } public Gpu gpu { get; set; } public Cpu cpu { get; set; } public Lidar lidar { get; set; } public Camera1 camera1 { get; set; } public Camera2 camera2 { get; set; } public Camera3 camera3 { get; set; } public Camera4 camera4 { get; set; } public Imu imu { get; set; } } public class Gpu { public string status { get; set; } public string value { get; set; } public string memory { get; set; } public string utilisation { get; set; } } public class Imu { public string status { get; set; } } public class Lidar { public string status { get; set; } } public class Root { public Dex dex { get; set; } }
对应JSON数据
[ {"dex": { "current_job": {"job":null, "task": null, "location": null}, "battery": {"status": "good", "value": "100"}, "gpu": {"status": "bad", "value": "97", "memory":"60", "utilisation":"83.3"}, "cpu": {"status": "good", "value": "32", "temperature":"37", "ram":"31.5", "utilisation":"26"}, "lidar": {"status": "good"}, "camera1": {"status": "good"}, "camera2": {"status": "good"}, "camera3": {"status": "error"}, "camera4": {"status": "good"}, "imu": {"status": "good"} } } ]
优化后类结构(传感器类继承SensorComponents)
using System.Text; using Microsoft.Bot.Builder; using System.Collections.Generic; using Newtonsoft.Json; using System.IO; namespace CoreBot.CognitiveModels { public class Battery { public string status { get; set; } public string value { get; set; } } public class Camera1 : SensorComponents { public string status { get; set; } } public class Camera2 : SensorComponents { public string status { get; set; } } public class Camera3 : SensorComponents { public string name = "CPU"; public string status { get; set; } } public class Camera4 : SensorComponents { public string status { get; set; } } public class Cpu { public string name = "CPU"; public string status { get; set; } public string value { get; set; } public string temperature { get; set; } public string ram { get; set; } public string utilisation { get; set; } } public class CurrentJob { public object job { get; set; } public object task { get; set; } public object location { get; set; } } public class Dex { public CurrentJob current_job { get; set; } public Battery battery { get; set; } public Gpu gpu { get; set; } public Cpu cpu { get; set; } public Lidar lidar { get; set; } public Camera1 camera1 { get; set; } public Camera2 camera2 { get; set; } public Camera3 camera3 { get; set; } public Camera4 camera4 { get; set; } public Imu imu { get; set; } } public class Gpu { public string status { get; set; } public string value { get; set; } public string memory { get; set; } public string utilisation { get; set; } } public class Imu : SensorComponents { public string status { get; set; } } public class Lidar : SensorComponents { public string status { get; set; } } public class Root { public Dex dex { get; set; } } public class SensorComponents { public string name { get; set;} public string status { get; set;} } }
解决方案
思路1:使用类列表(基于抽象基类)
既然已经让传感器类继承SensorComponents,可以直接创建List<SensorComponents>存储所有传感器实例,遍历列表检查状态即可。注意给每个传感器设置正确名称,避免输出错误。
示例代码:
// 假设已完成JSON反序列化得到Root实例 Root root = JsonConvert.DeserializeObject<List<Root>>(jsonString)[0]; // 构建传感器列表 List<SensorComponents> sensors = new List<SensorComponents> { root.dex.lidar, root.dex.imu, root.dex.camera1, root.dex.camera2, root.dex.camera3, root.dex.camera4 }; // 给每个传感器设置名称(或在构造函数中初始化) root.dex.lidar.name = "lidar"; root.dex.imu.name = "imu"; root.dex.camera1.name = "camera1"; root.dex.camera2.name = "camera2"; root.dex.camera3.name = "camera3"; root.dex.camera4.name = "camera4"; // 遍历检查状态 foreach (var sensor in sensors) { if (sensor.status != "good") { Console.WriteLine($"{sensor.name} not good"); } }
更优雅的方式是在传感器类构造函数中初始化名称:
public class Lidar : SensorComponents { public Lidar() { name = "lidar"; } }
思路2:遍历Root类的属性(利用反射)
通过反射遍历Dex类的属性,筛选出继承自SensorComponents的对象,或包含status属性的对象,检查状态并使用属性名作为传感器名称。
示例代码:
Root root = JsonConvert.DeserializeObject<List<Root>>(jsonString)[0]; Dex dex = root.dex; // 获取Dex类的所有属性 var properties = typeof(Dex).GetProperties(); foreach (var prop in properties) { var value = prop.GetValue(dex); if (value == null) continue; // 处理传感器类型 if (value is SensorComponents sensor) { string sensorName = string.IsNullOrEmpty(sensor.name) ? prop.Name : sensor.name; if (sensor.status != "good") { Console.WriteLine($"{sensorName} not good"); } } // 额外处理Battery、Cpu、Gpu等非传感器但有status的类(按需选择) else { var statusProp = value.GetType().GetProperty("status"); if (statusProp != null) { string status = statusProp.GetValue(value) as string; if (status != null && status != "good") { Console.WriteLine($"{prop.Name} not good"); } } } }
注意事项
- 反射方式灵活但性能略低,适合实例数量少、场景固定的情况;
SensorComponents已包含status属性,传感器子类无需重复定义,否则会覆盖基类属性;- 示例使用Newtonsoft.Json反序列化,需确保项目已安装对应NuGet包。
内容的提问来源于stack exchange,提问作者ycyc
相关产品推荐
相关产品推荐

