views:

285

answers:

7

Okay, this is probably very simple but, I have the below "checks" (not at the same time) and the First ALWAYS evaluates to TRUE while the Second SEEMS to work. This actually happens in each place that the row value is a number or bool(Date seems fine...).

If I walk through the code in Debug it shows the value of row["PersonID"] as 162434, the same as tbxPersonID.EditValue. Is this just a basic and beginner truth about programming that I missed in my hodge-podge-self-education?

It seems, if I cast everything in question to a string first, I will be fine I would just like to know if I am correct and if there is a general rule as to what Types I would need to do this for?

Doesn't Work

if (row["PersonID"] != tbxPersonID.EditValue)
{
    row["PersonID"] = tbxPersonID.EditValue;
}
if (row["CitizenFlag"] != chkCitizen.EditValue)
{
    row["CitizenFlag"] = chkCitizen.EditValue;
    _whatChanged.Add("CitizenFlag");
}

Works

 if (row["PersonID"].ToString() != tbxPersonID.EditValue.ToString())
 {
     row["PersonID"] = tbxPersonID.EditValue;
 }

 if (row["CitizenFlag"].ToString() != chkCitizen.EditValue.ToString())
 {
     row["CitizenFlag"] = chkCitizen.EditValue;
     _whatChanged.Add("CitizenFlag");
 }
+2  A: 

Whats the type of EditValue or the right hand value? The problem is probably that EditValue is not of type string (maybe its a subclass or something) therefore when you are doing != or == on it its doing a memory address compare instead of the compare for a string therefore you are getting false instead of true

Daniel
+1  A: 

What type is EditValue?

shahkalpesh
+18  A: 

row["PersonID"] is of type object, which means that != and == will use reference identity. Basically you're comparing boxed values.

If you use:

if (!object.Equals(row["PersonID"], tbxPersonID.EditValue))

then you'll get value equality semantics, and I suspect you'll be okay - assuming that tbxPersonID really is an int, either boxed or not.

Just to make things concrete, here's a short but complete example to show what I'm talking about:

using System;

class Test
{
    static void Main()
    {
        object first = 2;
        object second = 2;

        // Compares reference equality: false
        Console.WriteLine(first == second);

        // Compares value equality: true
        Console.WriteLine(object.Equals(first, second));
    }
}
Jon Skeet
Thank you Jon, your example makes perfect sense! I am still in awe that Dev's like you and others with so much experience are willing to stop and explain something so trivial to a beginner like me.
Refracted Paladin
No trouble at all - and I wouldn't put too much faith in the idea that I have "so much experience." You should see sum of the dumb mistakes I make every day!
Jon Skeet
Thanks, As kind of a follow up, if it isn't beyond the scope of `comments`; is it a better idea to use `object.Equals()` vs `.ToString()`?
Refracted Paladin
@Jon, like misspelling "some"? :)
Jage
@Jage: Aargh. That's dreadful. Sincere apologies. @Refracted Paladin: It's not a good idea to create textual representations unless that's fundamentally what you want to compare. It depends though - do you want (object)123L to equal (object)123? (i.e. comparing a boxed long with a boxed int.) I'd argue that usually if you get to that stage, you've probably got other problems.
Jon Skeet
+1  A: 

I don't know about C#, but in some languages the test of equality is different for numeric values and strings. So here you have to force a string comparison before it works.

Does this tell us something?

pavium
A: 

I am guessing that the data type of row[] object is something like int (or bool) and the chkCitizen.EditValue is of a different data type. So you may be comparing '1' == 1 and having the result be false.

JasonRShaver
+1  A: 

Hi there.

Without the call to ToString(), your code is testing equality on two Objects rather then two numbers, thus the reason why it's not working.

By using ToString() your explicitly telling the code the get the values from the row[] and EditValue objects.

Cheers. Jas.

Jason Evans
A: 

"12345" != 12345

Andrew Lewis