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 个相同类型的对象没有评估为等效(在第一种方法中(?

C# 包含行为

您的第一个代码块是在循环中创建一个新实例,然后立即检查该确切实例是否已在集合中。它不可能 - 你刚刚创建了它。

你不妨这样写:

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.