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

返回类型为IEnumerable<U>却无法使用yield?技术疑问求解

问题分析与解答

你的问题核心在于迭代器块的返回类型必须是指定的接口,而不是接口的实现类。

虽然泛型约束where T : IEnumerable<U>保证了T是IEnumerable<U>的实现,但T本身可能是某个具体类(比如List<U>、HashSet<U>)。而C#的迭代器机制(yield return)只能生成实现了IEnumerable<T>/IEnumerable等接口的匿名迭代器对象,无法直接转换成你指定的T类型——编译器不知道如何把这个匿名迭代器对象转换成你的具体T类(比如没法自动把它变成List)。

你的Eval_B方法没问题,就是因为它直接返回IEnumerable<U>接口类型,完全符合MSDN里规定的迭代器允许的返回类型范围。

要修复Eval_A的错误,有两种可行思路:

  • 直接将返回类型改为IEnumerable<U>,和Eval_B保持一致,这是最简单通用的方案:
    public IEnumerable<U> Eval_A(T items)
    {
        foreach (var item in items)
            if (item.Equals(id))
                yield return item;
    }
    
  • 如果业务上必须返回T类型,那不能用迭代器块,得手动把过滤后的元素收集到T的实例中(这需要T具备可实例化的条件,且支持元素添加):
    class Filter<T, U>
        where T : IEnumerable<U>, ICollection<U>, new()
        where U : IEquatable<U>
    {
        private readonly U id;
    
        public Filter(U id) => this.id = id;
    
        public T Eval_A(T items)
        {
            T result = new T();
            foreach (var item in items)
                if (item.Equals(id))
                    result.Add(item);
            return result;
        }
    }
    

    注意:第二种方案需要额外添加ICollection<U>和new()的泛型约束,仅适用于支持添加元素的集合类型,通用性远不如第一种。

内容的提问来源于stack exchange,提问作者D G

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 00:41:04