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

时间:2014-07-30 18:53:17

标签: c# collections casting derived-class

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

public class ExtendedTypes : List<ExtendedType>
{
    public ExtendedTypes Active
    {
        get { return this.Where(x => x.IsActive).ToList(); } // Compile Error
    }
}

1 个答案:

答案 0 :(得分:0)

过滤现有列表

您提到您只想过滤现有列表而不保留副本。在这种情况下,创建List不会做,因为从子集创建列表将始终创建新集合,而不仅仅是过滤器。 List<T>不是懒惰评估的集合。

您可能需要做的是将Active定义为IEnumerable<ExtendedType>并直接返回Where的结果(使用LINQ的懒惰实现),或者,如果您& #39;在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是参考类型,您不必担心通过复制列表来制作项目本身的副本。如果您不介意使用相同的引用创建列表的副本,请使用我的原始答案:

编译器是正确的,因为ExtendedTypesList<ExtendedType>,而不是相反,ToList()创建List<ExtendedType>

然而,有一个简单的解决方法。而不是ToList,只需使用从集合初始化的构造函数创建一个新的ExtendedTypes

public class ExtendedTypes : List<ExtendedType>
{
    public ExtendedTypes (IEnumerable<ExtendedType> items) : base(items)
    {}

    public ExtendedTypes Active
    {
        get { return new ExtendedTypes(this.Where(x => x.IsActive)); } 
    }
}