C # contains behavior

Can someone explain why these two methods return different values?

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); } 

The first method contains 10 elements in the list, and the second - 1. Why is the first method (Contains ()) never evaluated as true?

I am trying to ask why are two objects of the same type with the same values ​​for each property that are not evaluated as equivalent (in the first method)?

+6
source share
5 answers

Your first block of code creates a new instance inside the loop, and then immediately checks to see if this exact instance is already in the collection. This cannot be - you just created it.

You could write like this:

 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); } 

The second block of code checks for the presence of any element in the collection with the corresponding identifier. Since you have hardcoded identifier 1, you are only going to add the element for the first time. Each instance created after that will return false in the if and will not be added.

You can change this behavior by changing the identifier:

 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); } 

Again, the if no longer needed, since you know that the identifier can no longer exist in the collection, so you can simply remove the check.

+3
source

This is because Contains() matches the Summary .. link, not the ID .

Every time you do

 var summary = new CustomerSummary() { ID = 1, Name = "foo", balance = 50.00 }; 

in your loop, you create a new instance of CustomerSummary and, therefore, the new link is saved in Summary , considering the values ​​of each property in CustomerSummary asre to be exactly the same ..

+2
source

List<T>.Contains method determines equality using the default equality List<T>.Contains . And here you are trying to compare two different objects. Both can have all the properties filled with the corresponding values, but these are two different objects. If you really want to use the Contains method here, you must implement the IEquatable<T>.Equals in your CustomerSummary object.

+2
source

hi in the first function that you are trying to use is contained on the whole object, and not on the property, as you do in the second function, try changing it first as

  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); } 
+1
source
 if (!summaries.Contains(summary)) 

This will check the entire set (string)

  { ID = 1, Name = "foo", balance = 50.00 } 

and

This will check the individual element Id=1.

0
source

Source: https://habr.com/ru/post/973745/


All Articles