C# 为什么可以';我不能使用这个嵌套的lambda表达式吗?

C# 为什么可以';我不能使用这个嵌套的lambda表达式吗?,c#,lambda,C#,Lambda,我试图维护来自各种查询的唯一模型列表。不幸的是,我们模型的equals方法没有定义,所以我不能轻易地使用散列映射 作为快速修复,我使用了以下代码: public void AddUnique( List<Model> source, List<Model> result) { if (result != null) { if (result.Count > 0 && source

我试图维护来自各种查询的唯一模型列表。不幸的是,我们模型的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);
    }
}
public void AddUnique(
列出来源,
列表结果)
{
如果(结果!=null)
{
如果(result.Count>0
&&源!=null
&&source.Count>0)
{
source.RemoveAll(
s=>result.Contains(
r=>r.ID==s.ID));
}
结果。添加范围(源);
}
}
不幸的是,这不起作用。当我一步一步地浏览代码时,我发现即使我已经检查以确保在
source
result
中至少有一个
Model
具有相同的
ID
,但
RemoveAll(谓词)
行不会更改
source
中的项数。我错过了什么

source.RemoveAll(source.Where(result.Select(r => r.ID).Contains(source.Select(s => s.ID))));

此语句的目标是对ID进行两次枚举,一次用于源,一次用于结果。然后,对于两个枚举中的每个元素,它将返回true到where语句。然后它将删除所有返回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);
        }
    }
}
公共静态类CollectionHelper
{
公共静态void RemoveWhere(此IList列表,Func选择器)
{
var itemsToRemove=list.Where(选择器).ToList();
foreach(itemsToRemove中的变量项)
{
列表。删除(项目);
}
}
公共静态void RemoveWhere(此IDictionary字典,Func选择器)
{
var itemsToRemove=dictionary.Where(selector.ToList();
foreach(itemsToRemove中的变量项)
{
删除(项);
}
}
}

上述代码甚至不应该编译,因为
包含
需要的是
模型,而不是谓词

您可以使用任意()来代替:


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

我可能会选择另一种方法来解决此问题

您说过在类中没有合适的平等实现。也许你改变不了。但是,您可以定义一个
IEqualityComparer
实现,该实现允许您在实际的
模型
类本身之外指定适当的
等于
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();
     }
}
类模型比较器:IEqualityComparer
{
公共布尔等于(x型、y型)
{
//省略验证
返回x.ID==y.ID;
}
public int GetHashCode(m型)
{
返回m.ID.GetHashCode();
}
}

这太疯狂了。你说得很对,但代码确实编译了。这到底是怎么回事?!?哦,孩子。显然
包含(这个IEnumerable谓词)
实际上是我们库中的一个扩展方法,其中有一个巨大的异常错误。非常感谢你让我调查这件事。我一定很喜欢那些巨大的虫子。
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();
     }
}