繁体   English   中英

为什么我不能使用这个嵌套的lambda表达式?

[英]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);
    }
}

不幸的是,这不起作用。 当我逐步完成代码时,我发现尽管我已经检查过确保在sourceresult中至少有一个具有相同ID Model ,但RemoveAll(Predicate<Model>)行不会更改数字source的项目。 我错过了什么?

上面的代码甚至不应该编译,因为Contains需要一个Model而不是谓词。

您可以使用Any()代替:

source.RemoveAll(s => result.Any(r => r.ID == s.ID));

这将正确地从源中删除项目。

我可能会选择以不同的方式解决问题。

你说你在类中没有合适的相等实现。 也许你不能改变它。 但是,您可以定义IEqualityComparer<Model>实现,该实现允许您在实际Model类本身外部指定适当的EqualsGetHashCode实现。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM