如何通过列表高效访问另一列表中对象的引用类型属性(不复制)
解决方案:创建自定义“视图”类实现无副本的属性访问
你要的是一个能直接映射原列表中实例属性的“视图”,不复制数据,同时拥有类似List的高效访问能力,完全可以通过自定义一个包装类来实现。
核心思路
这个视图类内部持有原List<MyClass>的引用,所有访问操作都直接代理到原列表的实例上,不存储任何属性副本,每次访问都实时读取原实例的prop1值。
代码实现
internal class MyClass { public string prop1; public string prop2; } // 自定义只读视图类,专门访问MyList中实例的prop1属性 public class Prop1ListView : IReadOnlyList<string> { private readonly List<MyClass> _source; public Prop1ListView(List<MyClass> sourceList) { _source = sourceList ?? throw new ArgumentNullException(nameof(sourceList)); } // 索引器直接返回原列表对应位置的prop1,无副本 public string this[int index] => _source[index].prop1; // 直接复用原列表的Count public int Count => _source.Count; // 枚举器直接遍历原列表的prop1 public IEnumerator<string> GetEnumerator() { foreach (var item in _source) { yield return item.prop1; } } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); }
使用示例
// 初始化原列表 List<MyClass> myList = new List<MyClass> { new MyClass { prop1 = "First", prop2 = "A" }, new MyClass { prop1 = "Second", prop2 = "B" } }; // 创建视图,无数据复制 var prop1View = new Prop1ListView(myList); // 直接通过索引访问,和List一样高效 Console.WriteLine(prop1View[0]); // 输出 "First" // 修改原实例的prop1,视图会实时同步 myList[0].prop1 = "Updated First"; Console.WriteLine(prop1View[0]); // 输出 "Updated First"
扩展支持修改(如果需要)
如果不仅要读,还要通过视图修改原实例的prop1,只需给索引器添加set逻辑:
public string this[int index] { get => _source[index].prop1; set => _source[index].prop1 = value; }
方案优势
- 零数据副本:视图仅持有原列表的引用,内存开销可以忽略
- 高效访问:索引访问是O(1)复杂度,和原生List一致;枚举性能和直接遍历原列表取属性几乎无差别
- 实时同步:原列表中实例的属性修改会立刻反映到视图中,反之通过视图修改也会同步到原实例
- 类型安全:严格对应
prop1的类型,避免类型转换问题
对比原有方案
- 比
IEnumerable<string>:支持索引访问,多次枚举不会重复执行Select逻辑,性能更稳定 - 比
ToList():无数据复制,内存占用更低,且数据实时同步,不会出现副本与原数据不一致的问题
内容的提问来源于stack exchange,提问作者whatever
相关产品推荐
相关产品推荐

