tags:

views:

450

answers:

3

I'm trying to compare two DataRows in a loop. However, the following if statement doesn't return true:

if (dt1.Rows[0]["Name"] == dt2.Rows[b]["Name"]) {
    // This never executes
}

However, if I add .ToString() to the end of each DataRow, the if statement returns true:

if (dt1.Rows[0]["Name"].ToString() == dt2.Rows[b]["Name"].ToString()) {
    // This now executes
}

The column "Name" is from the same table/column. So the question is quite simple... What am I doing wrong?

Thanks
Stephen

+8  A: 

Those cells hold objects so you are doing an object comparison, which just does a reference comparison, which is different from a value comparison. It asks the question "Are these two objects really the same object?", essentially are they referring to the same object, hence "reference comparison". When you do the ToString() call, you are then doing string comparison. That is why it works.

Here's a link to MS's discussion of Operator== and comparison.

itsmatt
Thanks. Is there any work around or is .ToString() the best I can do?
GateKiller
To add: if you cast both sides to string, it will work too.
leppie
+2  A: 

The == operator, if not overloaded, is identical to ReferenceEquals() -- that is, it determines whether two given objects are the same instances.

The call to ToString() returns an object of string class, which has overloaded == operator, which does string comparison.

Anton Gogolev
+1, very good explanation
muerte
Important: it's not an *overridden* == operator, it's an *overloaded* operator.
Jon Skeet
@Jon Skeet -- Very true, thanks. Edited.
Anton Gogolev
Thanks for explaining why my first method didn't work :)
GateKiller
+3  A: 

As itsmatt has said, your first snippet is doing a reference comparison. An alternative to calling ToString is to use Object.Equals:

if (Object.Equals(dt1.Rows[0]["Name"], dt2.Rows[b]["Name"])) {
    // stuff
}

The reason for using the static method instead of the instance method is to avoid problems with null references.

Jon Skeet
Thanks for the answer and code sample. I didn't really want to use .ToString(), it didn't feel right somehow :)
GateKiller