c# Linq除了不返回不同值的列表

本文关键字:列表 返回 Linq | 更新日期: 2023-09-27 18:11:08

我试图找到两个列表的差异。列表中,"y"与列表"x"相比,应该有一个唯一的值。但是,Except不返回差值。,"differences"List的count总是等于0。

List<EtaNotificationUser> etaNotifications = GetAllNotificationsByCompanyIDAndUserID(PrevSelectedCompany.cmp_ID);
IEnumerable<string> x = etaNotifications.OfType<string>();
IEnumerable<string> y = EmailList.OfType<string>();
IEnumerable<string> differences = x.Except(y,  new StringLengthEqualityComparer()).ToList();
   foreach(string diff in differences)
                {
                    addDiffs.Add(diff);
                }

在阅读了一些帖子和文章后,我创建了一个自定义比较器。比较器查看字符串长度(为了便于测试)并获得Hashcode,因为这是两个不同类型的对象(即使我将它们的类型转换为字符串),我认为这可能是问题所在。

class StringLengthEqualityComparer : IEqualityComparer<string>
{
    public bool Equals(string x, string y)
    {
        return x.Length == y.Length;
    }
    public int GetHashCode(string obj)
    {
        return obj.Length;
    }
}

这是我第一次使用Except听起来像是比较两个列表的一种很棒的优化方式,但是我不能让它工作。

更新

X -应该从数据库中保存电子邮件地址。GetAllNotificationsByCompanyIDAndUserID—从数据库返回电子邮件值。Y -应该保留UI网格中的所有电子邮件地址。

我要做的是检测是否有新的电子邮件被添加到网格中。因此,此时X将拥有过去条目的保存值。Y将有用户添加的任何尚未保存的新电子邮件地址。

c# Linq除了不返回不同值的列表

问题就在这里:

IEnumerable<string> x = etaNotifications.OfType<string>();

,但etaNotificationsList<EtaNotificationUser>,由于stringsealed,它们都不可能是stringOfType返回所有属于给定类型的实例——它不会将每个成员"转换"为该类型。

所以x总是空的。

也许你想:

IEnumerable<string> x = etaNotifications.Select(e => e.ToString());

如果EtaNotificationUser已经覆盖了ToString,以提供您想要比较的值。如果要比较的值在属性中,可以使用:

IEnumerable<string> x = etaNotifications.Select(e => e.EmailAddress);

或其他属性

您可能不得不为y做类似的事情(除非EmailList已经是我怀疑的List<string>)。

假设您已经验证了您的两个枚举对象x和y实际上包含您期望的字符串,我认为您的问题是您的字符串比较器。根据文档,Enumerable。Except "产生两个序列的集合差。集合差是指第一个序列中没有出现在第二个序列中的成员。"但是相等比较器将所有具有相同长度的字符串相等。因此,如果第一个序列中的字符串恰好与第二个序列中的字符串具有相同的长度,使用比较器将不会发现它们不同。

更新:是的,我刚刚测试了它:

public class StringLengthEqualityComparer : IEqualityComparer<string>
{
    public bool Equals(string x, string y)
    {
        return x.Length == y.Length;
    }
    public int GetHashCode(string obj)
    {
        return obj.Length;
    }
}

        string [] array1 = new string [] { "foo", "bar", "yup" };
        string[] array2 = new string[] { "dll" };
        int diffCount;
        diffCount = 0;
        foreach (var diff in array1.Except(array2, new StringLengthEqualityComparer()))
        {
            diffCount++;
        }
        Debug.Assert(diffCount == 0); // No assert.
        diffCount = 0;
        foreach (var diff in array1.Except(array2))
        {
            diffCount++;
        }
        Debug.Assert(diffCount == 0); // Assert b/c diffCount == 3.

自定义比较器没有断言,但标准比较器有。