簡體   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