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