C#合并两个相同值的列表

C#合并两个相同值的列表,c#,C#,这是我的客户课程: public class Clients { public string Email { get; set; } public string Name { get; set; } public Clients(string e, string n) { Email = e; Name = n; } 我想创建一个新列表,其中包含列表a和列表B中相同的客户端。 例如: 名单A——约翰、乔纳森、詹姆斯。。

这是我的客户课程:

public class Clients
{
    public string Email { get; set; }
    public string Name { get; set; }


    public Clients(string e, string n)
    {
        Email = e;
        Name = n;
    }
我想创建一个新列表,其中包含列表a和列表B中相同的客户端。 例如: 名单A——约翰、乔纳森、詹姆斯。。。。 名单B——玛莎、简、乔纳森。。。。 退订者-乔纳森

    public static List<Clients> SameClients(List<Clients> A, List<Clients> B)
    {
        List<Clients> Unsubscribers = new List<Clients>();
        Unsubscribers = A.Intersect(B).ToList();
        return Unsubscribers;
    }
公共静态列表SameClients(列表A、列表B)
{
列表取消订阅者=新列表();
退订者=A.Intersect(B.ToList();
退回退订者;
}

然而,由于某些原因,我得到了一个空列表,我不知道出了什么问题。

问题是,当您比较对象时,使用
Equals
Gethashcode
来比较它们。您可以重写这两种方法,并根据需要提供自己的实现……下面已经有了一个答案,介绍了如何重写这两种方法

然而,通常我更喜欢让我的实体/模型(或者你想叫它们的任何东西)非常简单,并且让比较实现细节远离我的模型。在这种情况下,您可以实现一个
IEqualityComparer
,并使用一个重载
Intersects
,该重载接受一个
IEqualityComparer

下面是一个仅基于
Name
属性的
iequalitycompraer
的示例实现

public class ClientNameEqualityComparer : IEqualityComparer<Clients>
{
    public bool Equals(Clients c1, Clients c2)
    {
        if (c2 == null && c1 == null)
           return true;
        else if (c1 == null | c2 == null)
           return false;
        else if(c1.Name == c2.Name)
            return true;
        else
            return false;
    }

    public int GetHashCode(Client c)
    {
        return c.Name.GetHashCode();
    }
}

这将产生您期望的结果…

问题是,在比较对象时,使用
Equals
Gethashcode
来比较它们。您可以重写这两种方法,并根据需要提供自己的实现……下面已经有了一个答案,介绍了如何重写这两种方法

然而,通常我更喜欢让我的实体/模型(或者你想叫它们的任何东西)非常简单,并且让比较实现细节远离我的模型。在这种情况下,您可以实现一个
IEqualityComparer
,并使用一个重载
Intersects
,该重载接受一个
IEqualityComparer

下面是一个仅基于
Name
属性的
iequalitycompraer
的示例实现

public class ClientNameEqualityComparer : IEqualityComparer<Clients>
{
    public bool Equals(Clients c1, Clients c2)
    {
        if (c2 == null && c1 == null)
           return true;
        else if (c1 == null | c2 == null)
           return false;
        else if(c1.Name == c2.Name)
            return true;
        else
            return false;
    }

    public int GetHashCode(Client c)
    {
        return c.Name.GetHashCode();
    }
}

这将产生您期望的结果…

Intersect
默认情况下使用
GetHashCode
等于
,但您没有覆盖它,因此使用了它。由于所有客户端实例都是用
new
初始化的,因此即使它们的值相等,它们也是单独的实例。这就是为什么
Intersect
“认为”没有公共客户机的原因

所以你有几个选择

  • 实现自定义的
    IEqualityComparer
    并将其传递给
    Intersect
    (或许多其他LINQ方法)。这样做的好处是,您可以针对不同的需求实现不同的比较器,并且不需要修改原始类
  • 客户端
    覆盖
    等于
    GetHashCode
    和/或
  • 客户端
    实现
    IEquatable
例如(显示最后两个,因为其他答案已经显示了
IEqualityComparer
):

公共类客户端:IEquatable
{
公共字符串电子邮件{get;set;}
公共字符串名称{get;set;}
公共客户端(字符串e、字符串n)
{
电子邮件=e;
Name=n;
}
公共覆盖布尔等于(对象对象对象)
{
返回obj是Clients&&this.Equals((Clients)obj);
}
公共bool等于(其他客户)
{
返回电子邮件==其他?电子邮件==真
&&Name==other?.Name==true;
}
公共覆盖int GetHashCode()
{
未经检查
{
int hash=17;
hash=hash*23+(电子邮件?.GetHashCode()??0);
散列=散列*23+(名称?.GetHashCode()??0);
返回散列;
}
}
}
值得一读:


Intersect
默认情况下使用
GetHashCode
等于
,但您没有覆盖它,所以使用了它,它只是。由于所有客户端实例都是用
new
初始化的,因此即使它们的值相等,它们也是单独的实例。这就是为什么
Intersect
“认为”没有公共客户机的原因

所以你有几个选择

  • 实现自定义的
    IEqualityComparer
    并将其传递给
    Intersect
    (或许多其他LINQ方法)。这样做的好处是,您可以针对不同的需求实现不同的比较器,并且不需要修改原始类
  • 客户端
    覆盖
    等于
    GetHashCode
    和/或
  • 客户端
    实现
    IEquatable
例如(显示最后两个,因为其他答案已经显示了
IEqualityComparer
):

公共类客户端:IEquatable
{
公共字符串电子邮件{get;set;}
公共字符串名称{get;set;}
公共客户端(字符串e、字符串n)
{
电子邮件=e;
Name=n;
}
公共覆盖布尔等于(对象对象对象)
{
返回obj是Clients&&this.Equals((Clients)obj);
}
公共bool等于(其他客户)
{
返回电子邮件==其他?电子邮件==真
&&Name==other?.Name==true;
}
公共覆盖int GetHashCode()
{
未经检查
{
int hash=17;
hash=hash*23+(电子邮件?.GetHashCode()??0);
散列=散列*23+(名称?.GetHashCode()??0);
返回散列;
}
}
}
值得一读:


您比较的是类,而不是该类的属性。您需要在
客户机
类中重写
Equal
GetHashCode
。下面是一个示例,您确定这两个列表中的
Jonathan
的实例相同吗?听起来它们不一样,所以列表当然是空的。要比较类列表,请实现自己的比较器
public class Clients : IEquatable<Clients>
{
    public string Email { get; set; }
    public string Name { get; set; }


    public Clients(string e, string n)
    {
        Email = e;
        Name = n;
    }

    public override bool Equals(object obj)
    {
        return obj is Clients && this.Equals((Clients)obj);
    }

    public bool Equals(Clients other)
    {
        return Email == other?.Email == true
            && Name == other?.Name == true;
    }

    public override int GetHashCode()
    {
        unchecked 
        {
            int hash = 17;
            hash = hash * 23 + (Email?.GetHashCode() ?? 0);
            hash = hash * 23 + (Name?.GetHashCode() ?? 0);
            return hash;
        }
    }
}