C#为包装类列表实现ICollection<T_key>且不新建列表的实现方法
实现方案
首先明确:C# 没有内置的集合投影转发语法,你可以通过自定义 ICollection<T_key> 轻量包装类实现需求,该包装仅持有原 DataList 的引用,不会复制任何元素数据,完全满足「不生成全新List、仅转发Key成员」的要求。
实现代码
首先在你的 MyCollection 类中新增私有嵌套包装类:
private class KeyCollectionWrapper : ICollection<T_key> { private readonly List<T_wrapper> _source; public KeyCollectionWrapper(List<T_wrapper> source) { _source = source ?? throw new ArgumentNullException(nameof(source)); } // 直接转发原集合的Count public int Count => _source.Count; // 只读场景设为true即可,可按需调整 public bool IsReadOnly => true; // 迭代时直接返回每个元素的Key,无额外拷贝 public IEnumerator<T_key> GetEnumerator() { foreach (var item in _source) { yield return item.Key; } } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); public void CopyTo(T_key[] array, int arrayIndex) { if (array == null) throw new ArgumentNullException(nameof(array)); if (arrayIndex < 0) throw new ArgumentOutOfRangeException(nameof(arrayIndex)); if (array.Length - arrayIndex < Count) throw new ArgumentException("目标数组空间不足"); for (int i = 0; i < _source.Count; i++) { array[arrayIndex + i] = _source[i].Key; } } // 只读场景下修改方法直接抛出不支持异常即可,若需要支持修改可自行实现对应逻辑 public void Add(T_key item) => throw new NotSupportedException("Key集合为只读"); public bool Remove(T_key item) => throw new NotSupportedException("Key集合为只读"); public void Clear() => throw new NotSupportedException("Key集合为只读"); public bool Contains(T_key item) { foreach (var entry in _source) { if (EqualityComparer<T_key>.Default.Equals(entry.Key, item)) return true; } return false; } }
然后修改你的 GetKeyCollection 属性实现:
public ICollection<T_key> GetKeyCollection { get { // 仅创建轻量包装对象,无集合拷贝 return new KeyCollectionWrapper(DataList); } }
补充说明
- 该实现的开销极低,
KeyCollectionWrapper仅持有一个引用字段,实例化成本可以忽略 - 若你的使用场景允许修改返回接口类型为
IReadOnlyCollection<T_key>,实现逻辑可以更简洁,核心思路完全一致 - 如果需要支持通过Key集合修改原集合,可以对应实现
Add/Remove等方法,操作原DataList即可
内容的提问来源于stack exchange,提问作者Sean Wagemans
相关产品推荐
相关产品推荐

