1

I have 2 variables:

object Id = itemType.GetProperty(dataValueField).GetValue(item, null); //=0;

object selectedValue = 0;

And want to compare them.

I have tried:

var a = Id.Equals(selectedValue);
var b = Id == selectedValue;
var c = Object.Equals(Id, selectedValue);
var d = var x = Object.Equals((Object)Id, (Object)selectedValue);

But everything returns false;


Update: Id is typeof Int64? and selectedValue is Int32? but == operator works for Int64? and Int32?

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
David Maisuradze
  • 824
  • 2
  • 12
  • 27

4 Answers4

3

You are comparing the instance and thats why they are different. Do you have to use an object? Could you cast it to an int ?

You could use a custom class and override Equals() and the operator ==. Take a look at: https://msdn.microsoft.com/en-us/library/ms173147.aspx

I hope it helps.

zanseb
  • 1,275
  • 10
  • 20
  • Yes, agreed. But Id and selectedValue should be String types too. Actually are object type parameters in function and I can pass any type of value in this function – David Maisuradze Nov 18 '16 at 08:06
  • Is it possible to make it generic? (https://msdn.microsoft.com/en-us/library/512aeb7t.aspx) – zanseb Nov 18 '16 at 08:09
  • It could be written like this: `int Id = itemType.GetProperty(dataValueField).GetValue(item, null);` – zanseb Nov 18 '16 at 08:10
  • Generic function would be great idea but GetValue() is not generic type function, s I can't write `int Id = itemType.GetProperty(dataValueField).GetValue(item, null);` – David Maisuradze Nov 18 '16 at 08:50
  • You could write a generic wrapper method which does the casting for you. But it's hard to make a conclusion without knowing the code in depth. I hope i helped a bit :) – zanseb Nov 18 '16 at 09:34
2

I am pretty sure there is a problem with your data types, not the values. If you for example take 0L (long) and an integer with value 0, all ways to check equality return false. If both have the same type (int) for example, it works.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
  • Id is typeof Int64? and selectedValue is Int32? but == operator works for Int64? and Int32? – David Maisuradze Nov 18 '16 at 07:57
  • Nope, not this way. `bool x = object.Equals((object)0, (object)0L)` returns false. `bool x = object.Equals((object)0, (object)0)` returns true. – Patrick Hofman Nov 18 '16 at 07:59
  • Yes, agreed. But I am talking about == operator not about Object.Equals(). == operator works fine for Int64? and Int32? – David Maisuradze Nov 18 '16 at 08:05
  • If they both are typed the right way. You are now comparing objects, not primitive types. There is more logic behind comparing than just the values. – Patrick Hofman Nov 18 '16 at 08:06
  • Yes, indeed and this is my problem that == and Object.Equals() are not working for me. If I cast these object types to Int64? and Int32? it will work. But Id and selectedValue are object type parameters for function and I can pass any type of value in this function – David Maisuradze Nov 18 '16 at 08:08
  • Yes, it will work then. Make sure to cast them to an `long?` and you will be fine. – Patrick Hofman Nov 18 '16 at 08:09
2

Id is typeof Int64? and selectedValue is Int32? but == operator works for Int64? and Int32?

You are right that those types compare properly:

Int64? Id = 0;
Int32? selectedValue = 0;

Console.WriteLine(Id == selectedValue); // indeed true

However, your types are objects, so you have to keep in mind that what actually happens is a comparison of objects:

object IdAsObject = Id;
object selectedValueAsObject = selectedValue;

Console.WriteLine(IdAsObject.Equals(selectedValueAsObject));
Console.WriteLine(IdAsObject == selectedValueAsObject);
Console.WriteLine(Object.Equals(IdAsObject, selectedValueAsObject));
Console.WriteLine(Object.Equals((Object)IdAsObject, (Object)selectedValueAsObject));

And these are all false, since two objects are only equal if they are the same object.

If you want to compare the values, you should make sure to use proper types.

poke
  • 369,085
  • 72
  • 557
  • 602
  • So I have to cast Id and selectedValue to Int64? and Int32? and compare them after this? There is no solution? – David Maisuradze Nov 18 '16 at 08:10
  • This statement is not correct: `since two objects are only equal if they are the same object`. The `Equals` method has been overridden in Int32 and Int64. The problem here is that the override does a type check first and the type of an Int32 is not the same as an Int64. For now reference, see http://www.dotnetframework.org/default.aspx/4@0/4@0/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/clr/src/BCL/System/Int64@cs/1305376/Int64@cs. If you want to check it yourself, change both the `Id` and `selectedValue` to be an `int32` (and cast to object) and do an `idAsObect.Equals(selectedValueAsObject) – kha Nov 18 '16 at 08:15
1

Have a look at the source code for Int64 and Int32. Excerpt from Int64:

http://www.dotnetframework.org/default.aspx/4@0/4@0/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/clr/src/BCL/System/Int64@cs/1305376/Int64@cs

    public override bool Equals(Object obj) {
        if (!(obj is Int64)) {
            return false; 
        }
        return m_value == ((Int64)obj).m_value; 
    } 

If you notice, the first thing the Equals does is a type check. The types are not compatible and your only solution will be to either cast the Int32 to an Int64 or write a custom Equals that does what you need.

And some test to demonstrate:

public class Blah
{
    public Int32 Id32 { get; set; }
    public Int64 Id64 { get; set; }
}

private void DoTest()
{
    var blah = new Blah
    {
        Id32 = 1,
        Id64 = 1
    };

    object idInt32 = blah.GetType().GetProperty("Id32").GetValue(blah, null);
    object idInt64 = blah.GetType().GetProperty("Id64").GetValue(blah, null);
    object selectedValue = 1; // default type is Int32

    bool areTheSameInt = idInt32.Equals(selectedValue); // true
    bool areTheSameLong = idInt64.Equals(selectedValue); // false
}
kha
  • 19,123
  • 9
  • 34
  • 67