0

I have a DataTable and I created a DataView from the DataTable. I grab a record from the DataTable (Let's say record 5). Then I sort the DataView and I am trying to find the new index of the record I grabbed prior to sorting the DataView.

So to find the location of the new record I will loop through each record and each item in the record until I find a record that has all matching items in the record.

My loop looks like this:

int currentRecord = 2;
DataRow tr = view.Table.Rows[currentRecord];

view.Sort = "Name ASC";

foreach (DataRowView drv in view)
{
    foreach(object itemA in tr.ItemArray)
    {
        foreach (object itemB in drv.Row.ItemArray)
        {
            Console.WriteLine("{0} == {1}", itemA, itemB);
            if(itemA == itemB)
            {
                Console.WriteLine("Match!");
            }
        }
    }
}

This is my output: enter image description here enter image description here

So as you can see here in the pictures it's returning true for object{string} but false for object{int} even when the values are the same.

What's going on here?

awh112
  • 1,466
  • 4
  • 22
  • 34
Auios
  • 11
  • 5
  • See also https://stackoverflow.com/questions/35008317/compare-two-integer-objects-for-equality-regardless-of-type – NineBerry Jun 07 '18 at 16:42
  • 2
    If your value types are boxed compare them with `.Equals()` instead of `==`. – Jonathon Chase Jun 07 '18 at 16:44
  • @JonathonChase that did the trick! Thanks! :) – Auios Jun 07 '18 at 16:46
  • @Auios It is actually possible to directly compare tr with drv.Row in your code to find the row. The DataView directly uses the DataRows from the DataTable, so comparing the referrences to DataRow works. This goes a lot faster than comparing the actual values in the row... – NineBerry Jun 07 '18 at 17:13
  • @NineBerry You're right. I am over complicating things. I've adjusted my code to tr.Equals(view[i].Row); now – Auios Jun 07 '18 at 18:03
  • It is actually better to use == instead of Equals() in this case because you actually want to compare the reference and not the content – NineBerry Jun 07 '18 at 18:54
  • As an additional proof of the problems of comparing boxed values, try this: `ReferenceEquals(10, 10)`, this will return `false` because the two `10`s are boxed independently and thus ends up as two distinct objects on the heap, both containing a boxed int. – Lasse V. Karlsen Jun 07 '18 at 19:44
  • @LasseVågsætherKarlsen Would it be faster to use ReferenceEquals or == then? – Auios Jun 08 '18 at 15:06
  • It doesn't matter, `ReferenceEquals` is *defined* as `objA == objB` and will usually be inlined if you actually manage to call it. However, a normal call to `ReferenceEquals` on two `object` variables will be compiled as a `ceq` instruction, exactly the same as `==` will, so they are in fact the same. Use whatever you feel is most appropriate for you and your team to understand what is going on. Personally I would use ReferenceEquals to make it 100% clear that we're dealing with the references and not the values, but again, it's the same either way. – Lasse V. Karlsen Jun 08 '18 at 17:10
  • Note that if you use the `==` operator and one of the operands is *not* an object, you might invoke something other than `ReferenceEquals` type of comparison though, which is why I prefer `ReferenceEquals` when I actually want reference comparison. – Lasse V. Karlsen Jun 08 '18 at 17:11
  • @LasseVågsætherKarlsen Thank you for the great tips! :) – Auios Jun 08 '18 at 18:45

0 Answers0