如何按用户指定属性顺序,从Strike类数组生成一维数组?
动态拼接Strike属性为一维数组的实现方案
要实现动态按配置顺序拼接属性值,必须用反射——因为要在运行时根据字符串名称获取属性值,硬编码的方式做不到动态适配。下面是具体的实现步骤和代码:
核心思路
- 提前把Strike的属性信息缓存起来,避免每次调用都触发反射,节省性能
- 按配置的属性顺序,遍历每个Strike对象,依次取出对应属性值
- 将所有属性值收集到列表中,最后转换为一维数组
完整代码示例
先补全Strike类的定义(方便对照理解):
public class Strike { public float Volume { get; private set; } public float Bid { get; private set; } public float Ask { get; private set; } public Strike(float volume, float bid, float ask) { Volume = volume; Bid = bid; Ask = ask; } }
接下来写一个扩展方法处理动态拼接逻辑:
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; public static class StrikeHelper { // 提前缓存属性信息,避免重复反射拖慢速度 private static readonly Dictionary<string, PropertyInfo> _strikeProps = typeof(Strike) .GetProperties(BindingFlags.Public | BindingFlags.Instance) .ToDictionary(p => p.Name, p => p, StringComparer.OrdinalIgnoreCase); public static float[] BuildFlattenedArray(this Strike[] strikes, string[] propertyOrder) { // 校验传入的属性名是否合法 var invalidNames = propertyOrder.Where(name => !_strikeProps.ContainsKey(name)).ToList(); if (invalidNames.Any()) { throw new ArgumentException($"无效属性名:{string.Join(", ", invalidNames)}"); } var resultList = new List<float>(); foreach (var strike in strikes) { foreach (var propName in propertyOrder) { // 通过反射获取属性值并转换为float类型 var value = (float)_strikeProps[propName].GetValue(strike); resultList.Add(value); } } return resultList.ToArray(); } }
使用示例
// 你的测试对象数组 var test = new Strike[] { new Strike(150f, 2.1f, 2.2f), new Strike(300f, 2.3f, 2.4f) }; // 配置你需要的属性顺序,比如先Bid再Volume最后Ask var targetOrder = new[] { "Bid", "Volume", "Ask" }; // 生成一维数组 var finalArray = test.BuildFlattenedArray(targetOrder); // 最终结果:[2.1, 150, 2.2, 2.3, 300, 2.4]
关键注意事项
- 缓存PropertyInfo是必要操作,反射单次开销不大,但重复反射会累积性能损耗
- 字典使用
StringComparer.OrdinalIgnoreCase,配置属性名时无需纠结大小写 - 加入参数校验,避免因手滑写错属性名导致程序异常
内容的提问来源于stack exchange,提问作者Dan Gordon
相关产品推荐
相关产品推荐

