How can I compare type values ​​obtained from Reflection "GetValue"?

I have this code that gets the value from the Test class and then converts it to the type that it is. It correctly prints as "Int32", but when I check the equality with another variable with the same value, it prints "false". I suspect that this is because it is testing referential equality and that 2 variables are still objects. Is there a way to compare them, bearing in mind that I will not know the type of value returned before execution (it can be a string, float, another class, etc.)?

class Test{public int y;} static void Main() { var test1 = new Test{y=1}; var test2 = new Test{y=1}; var fields = test1.GetType().GetFields(); var test1Value = fields[0].GetValue(test1); var test2Value = fields[0].GetValue(test2); var test1Converted = Convert.ChangeType(test1Value, test1Value.GetType()); var test2Converted = Convert.ChangeType(test2Value, test2Value.GetType()); Console.WriteLine(test1Converted); // prints Int32 Console.WriteLine(test1Converted == test2Converted); // prints false } 
+5
source share
3 answers

Convert call is not needed. The values ​​returned by GetValue are already int s. Simple casting gives the right result.

 private class Test { public int y; } private static void Main() { Test test1 = new Test { y = 1 }; Test test2 = new Test { y = 1 }; FieldInfo[] fields = test1.GetType().GetFields(); int test1Value = (int)fields[0].GetValue(test1); int test2Value = (int)fields[0].GetValue(test2); Console.WriteLine(test1Value); // prints Int32 Console.WriteLine(test1Value == test2Value); // prints true } 

The reason non-locked values ​​fail is because Convert.ChangeType still returns an object , which is an attachment , so that you really get the reference equality.

Another way to get the correct value is to call the Equals method, which will be correctly redirected to Int32.Equals and print true :

 Console.WriteLine(test1Converted.Equals(test2Converted)); // prints true 

Please note that in this case Convert.ChangeType is still not required.

+3
source

Convert.ChangeType () to return an object. Move the returned object to Int32:

  var test1Converted = (Int32)Convert.ChangeType(test1Value, test1Value.GetType()); var test2Converted = (Int32)Convert.ChangeType(test2Value, test2Value.GetType()); 

Edit comment: Check if the type is IComparable, and then use this interface to compare:

  if (test1Converted is IComparable && test2Converted is IComparable) { var test1IComparable = (IComparable)test1Converted; var test2IComparable = (IComparable)test2Converted; bool equal = (test1IComparable == test2IComparable); } 
+1
source

In my understanding, the main problem here is that you are not aware of the class field of the test type until runtime, and you want to avoid explicit casting to integer types. Thus, we compare between two objects test1Converted and test2Converted, an easy way to override the Equals method of the type of the base object that will be called in == comparison. In the current case, test1Converted.Equals(test2Converted) will work, but if you have reference types, then you must override the Equals method for the correct result, if these are only type values, then there is no problem

-1
source

All Articles