如果我不能直接修改 class,如何使用元素类型的字段值从另一个列表中删除一个列表?

How can I remove a list from another list using a field value of the element's type if i can't modify the class directly?

假设我有一个名为 big 的对象 ProductList<Product>,它有 2 个字段,IDName。该列表已完全填充,这意味着每个元素的两个字段都不是 null,尽管它们可以是。

我有另一个 List<Product>,比第一个小,名为 small,但这次字段 Name 对于某些元素是 null,而 ID 始终存在。

我想从 big 中删除 small,其中 ID 相同。

示例:

List<Product> big = { {1,A},{2,B},{3,C},{4,D} };
List<Product> small = { {1,null},{3,C} };
List<Product> result = { {2,B},{4,D}};

我无法修改Product对象,即我无法实现IEquatable<Product>,并且没有实现这样的接口,意味着big.Except(small)big.RemoveAll(small)big.Contains(anElementOfSmall) 将不起作用(为了这个问题,我试过了)。

我想避免带有迭代器删除或类似功能的双循环,我正在搜索具有特定谓词的内置函数。

使用一个简单的谓词,您可以轻松实现它:

big.Where(p => !small.Any(o => o.id == p.id)).ToList();

翻译成:select 来自 big 其中元素 (p) 不足以满足 small 中元素 o 的情况具有相同的 ID.

为您的产品实施 IEqualityComparer,根据 ID 比较两个 Product。然后只需使用 Except 并传递比较器:

var result = big.Except(small, new ProductComparer()).ToList();

您需要告诉 Except 如何比较 Product 的实例。

public class ProductEqualityComparer : IEqualityComparer<Product>
{
    public bool Equals(Product x, Product y)
    {
        //they're both the same instance or they're both null
        if(ReferanceEquals(x, y))
            return true;

        //only one of them is null
        if(x == null || y == null)
            return false;

        return x.Id == y.Id;
    }

    public int GetHashCode(Product prod)
    {
        return prod == null? 0 : prod.Id.GetHashCode();
    }
}


big.Except(small, new ProductEqualityComparer())