You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现List<T>后使用LINQ无法转换回自定义集合类的问题

问题:继承List后无法将Where结果转换回自定义集合类型

我自定义了继承自List<Video>的VideoList类,调用Where()筛选后,没法把结果强制转回VideoList,试了网上各种方法都没解决。想知道有没有不用遍历重建集合的办法?

自定义类代码:

public class VideoList : List<Video>
{
    public VideoList GetVideos(bool onlyShorts)
        => (VideoList)this.Where(x => x.IsShort.Equals(onlyShorts)).ToList();
}

运行时抛出错误:

无法将类型为“WhereListIterator1[Video]”的对象强制转换为类型“VideoList”。


原因

Where()返回的是IEnumerable<Video>,调用ToList()后生成的是原生List<Video>对象,和你的VideoList是不同的类型,强制转换必然失败——这就像不能把普通List<Video>直接转成自定义的VideoList,类型层级不匹配。

解决方案

不存在无需遍历重建的办法,因为VideoList是自定义类型,.NET框架无法自动将原生List<Video>转换为它。但可以用更简洁的方式实现重建,不用手动写遍历循环:

方法1:添加自定义构造函数

给VideoList新增一个接受IEnumerable<Video>的构造函数,利用基类的构造函数初始化集合:

public class VideoList : List<Video>
{
    // 新增构造函数,接收IEnumerable<Video>初始化
    public VideoList(IEnumerable<Video> videos) : base(videos) { }

    public VideoList GetVideos(bool onlyShorts)
        => new VideoList(this.Where(x => x.IsShort.Equals(onlyShorts)));
}

这样直接用筛选后的IEnumerable<Video>创建新的VideoList,底层由框架处理遍历逻辑,代码更简洁。

方法2:使用AddRange方法

如果不想新增构造函数,也可以创建空的VideoList后用AddRange批量添加筛选结果:

public class VideoList : List<Video>
{
    public VideoList GetVideos(bool onlyShorts)
    {
        var filteredVideos = this.Where(x => x.IsShort.Equals(onlyShorts));
        var result = new VideoList();
        result.AddRange(filteredVideos);
        return result;
    }
}

额外建议

继承List<T>并非最佳设计实践,因为List<T>的方法都是非虚方法,无法重写。如果你的VideoList需要更多自定义行为,建议采用组合模式:内部封装一个List<Video>字段,对外暴露需要的方法和属性,这样扩展性和灵活性更强。


内容的提问来源于stack exchange,提问作者Dirk Bourgeois

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 04:16:14