代码之家  ›  专栏  ›  技术社区  ›  Furqan Safdar

如何将列表集合强制转换为派生集合对象?

  •  2
  • Furqan Safdar  · 技术社区  · 10 年前

    我创建了一个派生的集合对象,以引入一些附加功能来过滤集合中的活动记录,如下面的代码片段所示。如何实现这一点,因为我只想过滤相同的集合,同时在过滤器中保留原始引用而不创建副本。

    public class ExtendedTypes : List<ExtendedType>
    {
        public ExtendedTypes Active
        {
            get { return this.Where(x => x.IsActive).ToList(); } // Compile Error
        }
    }
    
    1 回复  |  直到 10 年前
        1
  •  0
  •   Furqan Safdar    10 年前

    筛选现有列表

    您提到您只想过滤现有列表而不保留副本。在本例中,创建 List 不会,因为从子集创建列表总是会创建一个新集合,而不仅仅是一个过滤器。 List<T> 不是延迟计算的集合。

    你可能需要做的是定义 Active IEnumerable<ExtendedType> 并返回 Where 直接(使用LINQ的懒惰实现),或者,如果您在WPF中,使用类似 CollectionView 作为 additional filter 在集合的顶部,如下所示:

    public ICollectionView ActiveTypes 
    {
        get
        {
            if (_activeTypes == null)
            {
                _activeTypes = CollectionViewSource.GetDefaultView(myExtendedTypes);
                _activeTypes.Filter = (type) => (type as ExtendedType).IsActive;
            }
            return _activeTypes;
        }
    }
    

    您现在可以绑定到 ActiveTypes 并仅获得原始列表的一个子集,该子集由 Filter 条款

    创建新列表

    然而,假设 ExtendedType 是引用类型,您不必担心通过复制列表来复制项目本身。如果您不介意创建 列表 对于相同的引用,请使用我的原始答案:

    编译器是正确的 ExtendedTypes 是-a List<ExtendedType> ,但不是相反,以及 ToList() 创建 列表<扩展类型> .

    然而,有一个简单的解决方法。而不是 ToList ,只需创建一个新 扩展的类型 具有从集合初始化的构造函数:

    public class ExtendedTypes : List<ExtendedType>
    {
        public ExtendedTypes (IEnumerable<ExtendedType> items) : base(items)
        {}
    
        public ExtendedTypes Active
        {
            get { return new ExtendedTypes(this.Where(x => x.IsActive)); } 
        }
    }