Why does comparison of entire model return false when each Individual properties return true

110 Views Asked by At

What I'm trying to do:

I want the user to choose a colorscheme in a combobox which I then use for some UI stuff later on execution (this works fine), but I then want to save that colorscheme and through MVVM and bindings make that item be selected in the combobox the next time the user opens the window and it doesn't work.

I made a model to hold my colorscheme:

[SettingsSerializeAs(SettingsSerializeAs.Xml)]
public class ColorScheme
{
    public int Id { get; set; }
    public SolidColorBrush ColorOne { get; set; }
    public SolidColorBrush ColorTwo { get; set; }
    public SolidColorBrush ColorThree { get; set; }
    public SolidColorBrush ColorFour { get; set; }
    public SolidColorBrush ColorFive { get; set; }
    public SolidColorBrush ColorSix { get; set; }
    public SolidColorBrush ColorSeven { get; set; }
    public SolidColorBrush ColorEight { get; set; }
    public SolidColorBrush ColorNine { get; set; }
    public SolidColorBrush ColorTen { get; set; }

}

I then store the colorscheme in the settings.settings file for the user but when I re-open the window the combobox is empty, even though the colorscheme contains the exact HEX-values for the colors.

When I test the comparison between the list of colorscheme and my stored colorscheme it returns false, but interestingly if I divide it out into seperate property comparisons it returns true on all of them:

foreach (var colorScheme in AllColorSchemes)
        {
            if (SelectProjectColorScheme != null)
            {

                if (colorScheme.Id == SelectProjectColorScheme.Id
                    || colorScheme.ColorOne == SelectProjectColorScheme.ColorOne
                    || colorScheme.ColorTwo == SelectProjectColorScheme.ColorTwo
                    || colorScheme.ColorThree == SelectProjectColorScheme.ColorThree
                    || colorScheme.ColorFour == SelectProjectColorScheme.ColorFour
                    || colorScheme.ColorFive == SelectProjectColorScheme.ColorFive
                    || colorScheme.ColorSix == SelectProjectColorScheme.ColorSix
                    || colorScheme.ColorSeven == SelectProjectColorScheme.ColorSeven
                    || colorScheme.ColorEight == SelectProjectColorScheme.ColorEight
                    || colorScheme.ColorNine == SelectProjectColorScheme.ColorNine
                    || colorScheme.ColorTen == SelectProjectColorScheme.ColorTen)
                {
                    var test = "yes";
                }

                if (colorScheme == SelectProjectColorScheme)
                {
                    var test = "yes";
                }
            }
        }

In the above code the first if statement returns true on all parameters, but the bottom returns false. I've tried changing between SolidColorBrushes, Brushes, converting HEX-values to brushes and using pre-defined brushes. Non of it works for me.

I'm at a loss for what could be causing this, and I'm hoping that there is workaround or a better way to do this that works. It should be a fairly simple task and I spend more than 3 days trying to fix it.

1

There are 1 best solutions below

1
On BEST ANSWER

Your model is a reference type, so when you call == it's actually checking reference equality (i.e. checking if they're just two different names for the same object rather than checking if they're two objects with the same values, which is what you really want). It is possible to override the == method to check the values, but reading this guide they recommend against this for mutable types. I'm not entirely sure why this is (quite possibly some deep programming philosophy), but their advice is to instead override Equals() to be a proper value check and call that instead. Note that if you go this route you should also override GetHashCode() (maybe just ^ all the hashcodes of the values together or something).

If on the other hand you change your model to a struct by default Equals() will do a value comparison but == will not work how you want it to unless you override it manually.

If you're using C#9 or later you might consider record types, which will do a value comparison if you call ==. Here are a couple more useful links, and best of luck.

https://learn.microsoft.com/en-us/dotnet/api/system.valuetype.equals?view=net-6.0#system-valuetype-equals(system-object)

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/equality-operators