C# 包含行为
本文关键字:包含行 | 更新日期: 2023-09-27 18:17:49
有人可以解释为什么这两种方法返回不同的值吗?
List<CustomerSummary> summaries = new List<CustomerSummary>();
for (var i = 0; i < 10; i++)
{
var summary = new CustomerSummary() { ID = 1, Name = "foo", balance = 50.00 };
if (!summaries.Contains(summary))
summaries.Add(summary);
}
-
List<CustomerSummary> summaries = new List<CustomerSummary>();
for (var i = 0; i < 10; i++)
{
var summary = new CustomerSummary() { ID = 1, Name = "foo", balance = 50.00 };
if (!summaries.Any(s=> s.ID == summary.ID))
summaries.Add(summary);
}
第一种方法在列表中有 10 个项目,而第二个方法有 1 个项目。为什么第一个 ( Contains(( ( 方法从不计算为真?
我想问的是,为什么每个属性具有相同值的 2 个相同类型的对象没有评估为等效(在第一种方法中(?
您的第一个代码块是在循环中创建一个新实例,然后立即检查该确切实例是否已在集合中。它不可能 - 你刚刚创建了它。
你不妨这样写:
List<CustomerSummary> summaries = new List<CustomerSummary>();
for (var i = 0; i < 10; i++)
{
var summary = new CustomerSummary { ID = 1, Name = "foo", balance = 50.00 };
summaries.Add(summary);
}
第二个代码块是检查集合中是否存在具有匹配 ID 的任何项。由于您已将 ID 硬编码为 1,因此您只会在第一次添加项目。在此之后创建的每个实例都将在 if
语句中返回 false,并且不会添加。
您可以通过更改 ID 来更改该行为:
for (var i = 0; i < 10; i++)
{
var summary = new CustomerSummary { ID = i, Name = "foo", balance = 50.00 };
if (!summaries.Any(s=> s.ID == summary.ID))
summaries.Add(summary);
}
同样,if
语句甚至不再需要,因为您知道 ID 不可能已经存在于集合中,因此您可以删除检查。
那是因为Contains()
匹配Summary
的引用..而不是ID
。
每次你做一个
var summary = new CustomerSummary() { ID = 1, Name = "foo", balance = 50.00 };
在你的循环中,你创建了一个新的CustomerSummary
实例,因此一个新的引用存储在summary
中,认为CustomerSummary
中的每个属性的值完全相同。
List<T>.Contains
方法使用默认相等比较器确定相等性。在这里,您正在尝试比较两个不同的对象。两者都可能用匹配值填充所有属性,但这是两个不同的对象。如果要在此处真正使用 Include 方法,则必须在 CustomerSummary
对象中实现 IEquatable<T>.Equals
方法。
嗨,在您尝试使用的第一个函数中,它
包含在整个对象上,而不是像在第二个函数中那样在属性上尝试先更改
List<CustomerSummary> summaries = new List<CustomerSummary>();
for (var i = 0; i < 10; i++)
{
var summary = new CustomerSummary() { ID = 1, Name = "foo", balance = 50.00 };
if (!summaries.Select(s=>s.ID).Contains(summary.ID))
summaries.Add(summary);
}
if (!summaries.Contains(summary))
这将检查整个touple(行(
{ ID = 1, Name = "foo", balance = 50.00 }
和
这将检查单个元素Id=1.