【问题标题】:CS1929 - List<T> does not contain an implementation of Where() (using System.Linq)CS1929 - List<T> 不包含 Where() 的实现(使用 System.Linq)
【发布时间】:2020-07-13 07:53:51
【问题描述】:

一段时间以来一直在努力清除此编译器错误。

编译器错误:第 29 行 - 'List newCollection = tempCollection.Where(谓词);'

CS1929 'List' 不包含 'Where' 的定义和 最佳扩展方法重载 'ParallelEnumerable.Where(ParallelQuery, Func)' 需要“ParallelQuery”类型的接收器

从代码 sn-p 中可以看出,我试图从 Linq 库中调用扩展方法 Where(),并使用谓词作为输入 arg。我试图调用它的集合是List&lt;T&gt; - 值得注意的是,我试图允许这种新的扩展方法SnapFingers 接受T 类型的任何IEnumerable,我觉得这是我的问题产生于。我知道具体化可能会解决此问题,但我想尝试使其通用化。

代码如下:

using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;

namespace BootCamp.Chapter
{
    public static class SnapFingersLINQ
    {
        public static IEnumerable<T> SnapFingers<T>(this IEnumerable<T> items, Predicate<T> predicate = null)
        {
            if (!items.Any())
            {
                return default(List<T>);
            }
            else
            {
                if (predicate != null)
                {
                    
                    IEnumerable<T> shuffItems = LINQExtensions.Shuffle(items);
                    List<T> tempCollection = shuffItems.ToList();

                    List<T> newCollection = tempCollection.Where<T>(predicate);

                    int numToRemove = AmountToRemove(items);
                    newCollection.RemoveRange(0, numToRemove);
                    
                    return tempCollection;
                }
                else
                {
                    List<T> shuffItems = LINQExtensions.Shuffle(items).ToList();
                    int numToRemove = AmountToRemove(items);
                    shuffItems.RemoveRange(0, numToRemove);
                    return shuffItems;
                }
            }
        }

        private static int AmountToRemove<T>(IEnumerable<T> items)
        {
            int lengthCollection = items.Count();
            int numberOfElementsToRemove = lengthCollection / 2;
            if (lengthCollection % 2 == 0)
            {
                return numberOfElementsToRemove;
            }
            else
            {
                return numberOfElementsToRemove - 1;
            }
        }
    }
}

请注意,LINQExtensions.Shuffle() 只是返回一个新的洗牌集合,IEnumerable&lt;T&gt;(我知道存在 Linq 扩展“洗牌”,但这是训练营作业的一部分)。

对此的任何帮助将不胜感激!

【问题讨论】:

  • 您能否扩展一下,因为我已经进行了一些挖掘,但 MSDN 或其他帖子中的信息似乎对我没有帮助?

标签: c# linq generics


【解决方案1】:

Where extension method 需要 Func&lt;T, bool&gt; 类型的参数,而不是 Predicate&lt;T&gt;

将方法的签名更改为:

public static IEnumerable<T> SnapFingers<T>(this IEnumerable<T> items, Func<T, bool> predicate = null)

..然后在Where 之后添加ToList() 以避免另一个编译器错误:

List<T> newCollection = tempCollection.Where<T>(predicate).ToList();

【讨论】:

  • 谢谢,这是一个很好的方法,似乎是比使用 'x => predicate.Invoke(x)' @Caleb Manning 建议的“更好的实践”方法,尽管两者都工作一样。谢谢!
【解决方案2】:

我认为这里的问题是.Where 需要Func&lt;T, bool&gt; 类型的参数。试试List&lt;T&gt; newCollection = tempCollection.Where&lt;T&gt;(x =&gt; predicate.Invoke(x)).ToList();

【讨论】:

  • 这非常有效,谢谢!我认为这不可能是我没有将函数传递给它,但现在这很有意义。非常感谢!
【解决方案3】:

IEnumerable&lt;T&gt;.Where 方法采用 Func&lt;T, bool&gt; 而不是 Predicate&lt;T&gt;。是的,它们本质上是相同的,但是委托类型具有不同的类型标识,即使它们在功能上是相同的。

奇怪的是,下周我将为我的扩展团队举办一次午餐和学习会议,这是我的例子之一

【讨论】:

  • 谢谢!将成为您午餐和学习的好话题!
【解决方案4】:

更新: 您应该将方法SnapFingers&lt;T&gt; 的第二个参数的类型更改为Func&lt;T, bool&gt; predicate,因为方法Where&lt;T&gt; 接受该类型而不是Predicate&lt;T&gt;

原文:

试试List&lt;T&gt; newCollection = tempCollection.Where&lt;T&gt;(predicate).ToList();

说明:Linq的方法Where返回IEnumerable&lt;T&gt;,需要使用ToList转成List&lt;T&gt;

【讨论】:

  • 只是试了一下,编译器错误没有改变。我是不是想在这里太笼统了?谢谢你!
  • @Equilibrium23 我已经更新了我的答案,看看吧。
猜你喜欢
  • 2018-12-25
  • 2011-09-09
  • 1970-01-01
  • 2011-10-09
  • 2012-08-23
  • 1970-01-01
  • 1970-01-01
  • 2017-03-05
  • 1970-01-01
相关资源
最近更新 更多