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
(或许多其他LINQ方法)。这样做的好处是,您可以针对不同的需求实现不同的比较器,并且不需要修改原始类Intersect
- 让
覆盖客户端
和等于
和/或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
(或许多其他LINQ方法)。这样做的好处是,您可以针对不同的需求实现不同的比较器,并且不需要修改原始类Intersect
- 让
覆盖客户端
和等于
和/或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;
}
}
}