C#中结构体数组批量更新Range属性的优化方案问询
解决方案
首先明确:你提到的desc.Route.Select(i => i.Range = i.End - i.Start)不可行。因为Route是值类型(结构体),Select遍历到的每个i都是原数组元素的副本,修改副本的Range不会影响原数组中的真实元素,最终原数组的Range属性不会有任何变化。
接下来提供几种可行的优化/替代方案:
1. 优化原for循环
原循环本身已经很高效,但可以做小调整提升可读性和性能:
- 用数组的
Length代替Count(数组的Length是直接访问字段,比Count的属性访问更快) - 提前缓存数组引用,减少重复访问:
var routes = dest.Route; for (int i = 0; i < routes.Length; i++) { var route = routes[i]; route.Range = route.End - route.Start; routes[i] = route; // 注意:值类型必须重新赋值回数组 }
注:原代码里dest.Route[i].Range = ...能生效,是因为C#允许直接对数组中的值类型字段进行赋值(语法糖,本质是先取出副本,修改后再放回),上面的写法和原代码效果一致,但缓存数组和元素的方式在循环次数极多时能略提性能。
2. 使用LINQ生成新数组
如果允许替换原数组,可以用LINQ创建一个新的Route数组,避免手动循环:
dest.Route = dest.Route.Select(r => new Route { Start = r.Start, End = r.End, Range = r.End - r.Start, InConstruction = r.InConstruction }).ToArray();
这种方式代码更简洁,但会创建新数组,适合对内存占用不敏感的场景。
3. 把Range改为计算属性(推荐)
从设计角度看,Range是End - Start的派生值,完全可以不用存储,改成只读计算属性,这样就不需要手动更新,从根源上避免批量操作的需求:
public struct Route { public float Start; public float End; public bool InConstruction; // 计算属性,实时返回差值 public float Range => End - Start; };
这样无论Start或End怎么变化,Range都会自动返回正确的差值,不需要任何批量更新操作,是最优雅的解决方案。
内容的提问来源于stack exchange,提问作者user14645785
相关产品推荐
相关产品推荐

