-2

I'm making a noughts and crosses game in C# (WPF). This section of code is part of what happens after a player chooses a square to put their next piece in - it uses a method to convert the square's coordinates into a single integer which it can compare to each Image's Tag (1-9) to find the correct Image, which it then changes the Source of. Images, Sources and Tags are WPF-specific but all that is important to this problem is that I have a list of Images, each of which has a Tag, which is an object.

int coordNumber = ReturnNumber(coordinates); //get integer version of coordinates, equivalent to clickedSquare
string coordString = coordNumber.ToString();
object coordObject = coordString;

SquareImages.First(image => image.Tag == coordObject).Source = new ImageSourceConverter().ConvertFromString("Data/Images/Cross.png") as ImageSource;

The .Source part of the last line is not relevant as it happens after the error. The second and third lines are an attempt to see if casting different ways will change whether it can find an Image with the right Tag, but so far hasn't led to any changes. Two lines have been removed but did not affect the List or shown variables in any way.

  • 1
    When you compare objects, the only comparison that will be made is if they reference the exact same object. It will not do a string comparison. You could do: `image.Tag?.ToString() == coordString` – Silvermind Feb 06 '20 at 09:43
  • 1
    `Tag` is of type `object`, so if you stuff an `int` into it, it will be [boxed](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/types/boxing-and-unboxing). That means a separate object for each `Tag` regardless of the value of the `int`. (When you compare reference type objects using `==`, by default it's a comparision of the reference values, i.e. the underlying pointers) – Matthew Watson Feb 06 '20 at 09:43
  • 1
    Does this answer your question? [Compare String and Object in C#](https://stackoverflow.com/questions/21278322/compare-string-and-object-in-c-sharp) – Silvermind Feb 06 '20 at 09:44
  • If ``image.Tag`` is of type ``object`` but you are positive it actually contains an int, unbox the int, and compare it to your ``coordNumber`` like so: ``SquareImages.First(image => (int)image.Tag == coordNumber)``. – dumetrulo Feb 06 '20 at 10:00

1 Answers1

-1

The fixed code segment:

int coordNumber = ReturnNumber(coordinates); //get integer version of coordinates, equivalent to clickedSquare
string coordString = coordNumber.ToString();

SquareImages.First(image => (string) image.Tag == coordString).Source = new ImageSourceConverter().ConvertFromString("Data/Images/Cross.png") as ImageSource;

The answer was essentially what dumetrulo said, except it turned out the Tag could be converted to a string and not an int.

  • If this is the answer, the underlying object was already a string (not an int), and just needed casting from ``object`` to ``string``, as you did here. Reason being that ``string`` implements structural identity, i.e. it compares the characters, while ``==`` on ``object`` will do simple reference equality. – dumetrulo Feb 06 '20 at 14:02