方法名称预期-使用lambda表达式错误
本文关键字:使用 lambda 表达式 错误 方法 | 更新日期: 2023-09-27 18:14:53
我正在自定义集合中实现Contains(T item)
方法。下面的工作(因为它基本上是微软实现的副本):
public class aCollection:IEnumerable<T>
{
T[] items;
public int Count{ get; private set;}
//...
public bool Contains(T item)
{
EqualityComparer<T> defaultComparer = EqualityComparer<T>.Default;
for (int i = 0; i < Count; i++)
if (defaultComparer.Equals(items[i], item))
return true;
return false;
}
}
然而,虽然来到这个解决方案,我已经尝试了另一种方式,但我无法理解构建失败的确切原因与Method name expected
错误:
public class aCollection:IEnumerable<T>
{
T[] items;
public int Count{ get; private set;}
//...
public bool Contains(T item)
{
for (int i = 0; i < Count; i++)
if ((x => x == item)(items[i])) //Method name expected
return true;
return false;
}
}
我在这里误解了lambdas的用法吗?是不是因为某种原因我不能使用它们或者我只是写错了表达式?
编辑:我希望函数做的是检查我的集合,以找出,如果它包含参数。for循环中的行应该将T[] items
中的现有元素与传递的T item
逐个进行比较,直到找到匹配并返回true
。或者,如果在整个数组中没有找到匹配项,则只返回false
。
提前感谢,
hlfrmn
Lambda表达式应转换为要使用的委托。下面的代码看起来很奇怪,但是使用lambda不会出现编译错误:
public bool Contains(T item)
{
for (int i = 0; i < Count; i++)
if (((Func<T, bool>)((T x) => x == item))(items[i]))
return true;
return false;
}
为了避免在每次迭代中创建新的委托,可以在循环之前存储它:
public bool Contains(T item)
{
Func<T, bool> comparer = (T x) => x == item;
for (int i = 0; i < Count; i++)
if (comparer(items[i]))
return true;
return false;
}
但是它仍然有一个重要的问题:操作符==
不是为泛型类型(如c++)定义的。我建议使用EqualityComparer<T>.Default
来比较值
不像这样使用:
for (int i = 0; i < Count; i++)
if ((x => x == item)(items[i]))
return true;
只需使用Any
LINQ方法并像这样传递lambda表达式:
if (items.Any(x => x == item))
return true;
如果出于某种原因需要使用lambda表达式作为函数(这似乎是你正在尝试做的),那么你可以这样做:
Expression<Func<T,bool>> lambda_expression = (x => x == item);
Func<T, bool> function = lambda_expression.Compile();
for (int i = 0; i < Count; i++)
{
if (function(items[i]))
return true;
}
如果您想使用您的方法,请将代码更改为
public bool Contains(T item)
{
for (int i = 0; i < Count; i++)
if (items[i].Equals(item))
return true;
return false;
}
这里是显式地遍历集合,所以不需要使用lambda。当你写这个if ((x => x == item)(items[i]))
-编译器不理解x
指的是什么!
如果你想使用lambda,你可以用一种更优雅的方式写,比如
public bool Contains(T item)
{
return items.Any(i => i.Equals(item));
}
注意:使用EquityComparer
默认,就像MSDN的例子一样,否则你会错过T
类型可能实现的任何EqualityComparer
。
如果你看到 CLR core libraries
,这就是 .Any()
是如何实现的
public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null) throw Error.ArgumentNull("source");
if (predicate == null) throw Error.ArgumentNull("predicate");
foreach (TSource element in source)
{
if (predicate(element)) return true;
}
return false;
}
因此,从实际的实现中,您可以看到它确实做了您想要做的事情。您可以在这个GitHub Repo中看到其他 Linq Enumerable Extensions
,并探索其他标准Linq方法的实现。
实际上,更好的解决方案是而不是来实现您自己的Contains()
方法。
既然您的自定义集合实现了IEnumerable<T>
,那么这意味着您可以免费获得所有IEnumerable<T>
LINQ扩展方法,包括Enumerable.Contains