繁体   English   中英

C#包含行为

[英]C# contains behaviour

有人可以解释为什么这两种方法返回不同的值?

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方法通过使用默认的相等比较器来确定相等性。 在这里,您试图比较两个不同的对象。 两者都可能具有填充匹配值的所有属性,但这些属性是两个不同的对象。 如果您想在此处真正使用Contains方法,则必须在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.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM