如何遍历C# struct静态属性,按运行时DeviceName匹配返回实例
解决根据DeviceName查找对应静态实例的问题
我懂你的困扰——直接拿单个静态实例很轻松,但要在运行时动态匹配就得靠反射来帮忙了。下面给你两种实用方案,从基础实现到性能优化都覆盖到:
基础反射遍历方案
通过反射获取DeviceDetailModel的所有公共静态属性,筛选出类型匹配的属性后,逐个取出实例对比DeviceName即可:
public struct DeviceDetailModel { // 你的原有静态实例定义 public static readonly DeviceDetailModel DT851P = new DeviceDetailModel("851P","v1","v2"); public static readonly DeviceDetailModel DT852P = new DeviceDetailModel("852P","v3","v4"); public static readonly DeviceDetailModel DT83P = new DeviceDetailModel("853P","v5","v6"); public static readonly DeviceDetailModel DT854P = new DeviceDetailModel("854P"); // 原有属性定义 public string DeviceName { get; private set; } public string Value1 { get; private set; } public string Value2 { get; private set; } // 完善构造函数,处理单参数初始化场景 private DeviceDetailModel(string deviceName) : this(deviceName, null, null) {} private DeviceDetailModel(string deviceName,string value1,string value2) { DeviceName = deviceName; Value1 = value1; Value2 = value2; } // 新增的动态查找方法 public static DeviceDetailModel? GetInstanceByDeviceName(string targetDeviceName) { // 获取所有公共静态属性 var staticProps = typeof(DeviceDetailModel).GetProperties(BindingFlags.Public | BindingFlags.Static); foreach (var prop in staticProps) { // 只筛选类型为DeviceDetailModel的属性 if (prop.PropertyType == typeof(DeviceDetailModel)) { // 静态属性无需实例,传null即可获取值 var instance = (DeviceDetailModel)prop.GetValue(null)!; if (instance.DeviceName == targetDeviceName) { return instance; } } } // 找不到匹配项时返回null(也可根据需求抛出异常) return null; } }
关键说明:
BindingFlags.Public | BindingFlags.Static:精准定位公共静态属性,避免拿到无关成员。prop.GetValue(null):静态属性不属于任何实例对象,传入null就能直接获取其值。- 补充了单参数构造函数,解决原代码中
DT854P初始化的编译问题。
性能优化方案(缓存实例)
反射操作有一定性能开销,如果这个查找会频繁调用,建议提前把所有静态实例缓存到字典里,后续直接通过字典快速查找:
public struct DeviceDetailModel { // 原有静态实例与属性定义 public static readonly DeviceDetailModel DT851P = new DeviceDetailModel("851P","v1","v2"); public static readonly DeviceDetailModel DT852P = new DeviceDetailModel("852P","v3","v4"); public static readonly DeviceDetailModel DT83P = new DeviceDetailModel("853P","v5","v6"); public static readonly DeviceDetailModel DT854P = new DeviceDetailModel("854P"); public string DeviceName { get; private set; } public string Value1 { get; private set; } public string Value2 { get; private set; } private DeviceDetailModel(string deviceName) : this(deviceName, null, null) {} private DeviceDetailModel(string deviceName,string value1,string value2) { DeviceName = deviceName; Value1 = value1; Value2 = value2; } // 静态缓存字典,仅初始化一次 private static readonly Dictionary<string, DeviceDetailModel> _deviceInstanceCache; // 静态构造函数,在第一次访问结构体时执行缓存初始化 static DeviceDetailModel() { _deviceInstanceCache = new Dictionary<string, DeviceDetailModel>(); var staticProps = typeof(DeviceDetailModel).GetProperties(BindingFlags.Public | BindingFlags.Static); foreach (var prop in staticProps) { if (prop.PropertyType == typeof(DeviceDetailModel)) { var instance = (DeviceDetailModel)prop.GetValue(null)!; _deviceInstanceCache[instance.DeviceName] = instance; } } } // 优化后的查找方法 public static DeviceDetailModel? GetInstanceByDeviceName(string targetDeviceName) { _deviceInstanceCache.TryGetValue(targetDeviceName, out var matchedInstance); return matchedInstance; } }
优势:
- 静态构造函数仅执行一次,把所有实例存入字典,后续查找都是O(1)的字典查询,性能远超每次反射遍历。
- 代码逻辑更简洁,维护成本更低。
使用示例
调用时直接传入目标DeviceName即可:
var matchedDevice = DeviceDetailModel.GetInstanceByDeviceName("853P"); // matchedDevice就是DT83P的实例
内容的提问来源于stack exchange,提问作者Ronak Shetiya
相关产品推荐
相关产品推荐

