Zer0
Zer0

Reputation: 1022

LINQ to check if class is in list

I've got a situation in which I have to handle adding custom objects in a list if they don't exist. So far I've got no luck.

I have a custom class called ImagePoint:

public class ImagePoint
{
    public List<string> Point { get; set; }
    public List<string> NameSize { get; set; }

    public ImagePoint(List<string> _Point, List<string> _NameSize)
    {
        Point = _Point;
        NameSize = _NameSize;
    }
}

I'm currently using JSON.NET to save and load my ImagePoint object. JSON saves the file with the output which looks like:

[
  {
    "Point": [
      "16 11"
    ],
    "NameSize": [
      "Preview Buttons",
      "27 11"
    ]
  },
  {
    "Point": [
      "16 0"
    ],
    "NameSize": [
      "Close Buttons",
      "27 11"
    ]
  }
]

I read the file and load the contents into my `imagePointsList':

List<ImagePoint> imagePoint = JsonConvert.DeserializeObject<List<ImagePoint>>(sr.ReadToEnd());
foreach (var item in imagePoint)
{
    imagePointsList.Add(item);
}

Now Before I want to add I first make a new ImagePoint object and assign the values to it like so:

string[] p, s;
ImagePoint image_point = new ImagePoint(new List<string>(), new List<string>());
image_point.NameSize.Add(tb_point_name.Text);

if (tb_position.Text.Contains(",")) //More than one Point
{
    p = tb_position.Text.Split(',');
    image_point.Point.AddRange(p);
}
else // One Point
{
    p = new string[1];
    p[0] = tb_position.Text;
    image_point.Point.AddRange(p);
}

if (tb_width_height.Text.Contains(",")) //More than one Size
{
    s = tb_width_height.Text.Split(',');
    image_point.NameSize.AddRange(s);
}
else // One Size
{
    s = new string[1];
    s[0] = tb_width_height.Text;
    image_point.NameSize.AddRange(s);
}

Then I check if the contents are the same using:

bool contains = imagePointsList.Any(item => item.Point.ToArray() == p);

Problem is that even when I load the json file and I know those points exist in the list (see the json output) I still get a False value from contains variable.

How can I efficiently check if list already has an item with the values p, if it does should contains should return True else False.

Upvotes: 0

Views: 711

Answers (2)

Alex Zhukovskiy
Alex Zhukovskiy

Reputation: 10025

contains variable will never be true because when you write item.Point.ToArray() .Net creates a new array, and then it compares it. But arrays doesn't have overloaded equality operator, thus they will be compared by reference. Because ToArray() just created a new array, it will never happen. You can use SequenceEqual from LINQ namespace or write your own comparer. And be careful with ToArray() calls in cycles because it adds a lot of pressure on GC.

Upvotes: 1

Tim Schmelter
Tim Schmelter

Reputation: 460228

== compares references of arrays not their content, try item.Point.SequenceEqual(p):

bool contains = imagePointsList.Any(item => item.Point.SequenceEqual(p));

Upvotes: 1

Related Questions