[英]Why can't I use this nested lambda expression?
我正在尝试从各种查询中维护一个独特模型列表。 不幸的是,我们的模型的equals方法没有定义,所以我不能轻易使用哈希映射。
作为快速修复,我使用了以下代码:
public void AddUnique(
List<Model> source,
List<Model> result)
{
if (result != null)
{
if (result.Count > 0
&& source != null
&& source.Count > 0)
{
source.RemoveAll(
s => result.Contains(
r => r.ID == s.ID));
}
result.AddRange(source);
}
}
不幸的是,这不起作用。 当我逐步完成代码时,我发现尽管我已经检查过确保在source
和result
中至少有一个具有相同ID
Model
,但RemoveAll(Predicate<Model>)
行不会更改数字source
的项目。 我错过了什么?
上面的代码甚至不应该编译,因为Contains
需要一个Model
而不是谓词。
您可以使用Any()代替:
source.RemoveAll(s => result.Any(r => r.ID == s.ID));
这将正确地从源中删除项目。
我可能会选择以不同的方式解决问题。
你说你在类中没有合适的相等实现。 也许你不能改变它。 但是,您可以定义IEqualityComparer<Model>
实现,该实现允许您在实际Model
类本身外部指定适当的Equals
和GetHashCode
实现。
var comparer = new ModelComparer();
var addableModels = newSourceOfModels.Except(modelsThatAlreadyExist, comparer);
// you can then add the result to the existing
您可以将比较器定义为
class ModelComparer : IEqualityComparer<Model>
{
public bool Equals(Model x, Model y)
{
// validations omitted
return x.ID == y.ID;
}
public int GetHashCode(Model m)
{
return m.ID.GetHashCode();
}
}
source.RemoveAll(source.Where(result.Select(r => r.ID).Contains(source.Select(s => s.ID))));
此语句的目标是生成两个ID枚举,一个用于源,一个用于结果。 然后,它将返回两个枚举中每个元素的where语句的true。 然后它将删除任何返回true的元素。
您的代码正在删除两个列表之间相同的所有模型,而不是那些具有相同ID的模型 。 除非它们实际上是模型的相同实例,否则它将无法像您期望的那样工作。
有时我会将这些扩展方法用于这种事情:
public static class CollectionHelper
{
public static void RemoveWhere<T>(this IList<T> list, Func<T, bool> selector)
{
var itemsToRemove = list.Where(selector).ToList();
foreach (var item in itemsToRemove)
{
list.Remove(item);
}
}
public static void RemoveWhere<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, Func<KeyValuePair<TKey, TValue>, bool> selector)
{
var itemsToRemove = dictionary.Where(selector).ToList();
foreach (var item in itemsToRemove)
{
dictionary.Remove(item);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.