I've stumbled across in interesting bug in some comparison code recently where two objects both have a property equal to 0.0m. When that property is converted to an int and compared, the comparison is never equal. Reproduction below:
Take an abstraction A, and two implementations, B and C:
public abstract class A
{
public decimal MyProp { get; set; }
}
public class B : A
{
}
public class C : A
{
}
The abstraction defines several public properties, primarily, but not entirely, decimal. All public properties are always primitives. The concrete subtypes represent this abstraction as obtained from two different data sources. Two objects of type A are considered equal if and only if all their public properties are equal. One caveat: all decimal properties should be converted to an int before comparison, using default rounding behavior (MidpointRounding.ToEven). This has resulted in the following comparison code:
private static bool Compare(A a1, A a2)
{
var propertiesList = typeof(A).GetProperties(BindingFlags.Instance | BindingFlags.Public).ToList();
foreach (var propertyInfo in propertiesList)
{
var value1 = propertyInfo.GetValue(a1);
var value2 = propertyInfo.GetValue(a2);
if (propertyInfo.PropertyType == typeof(decimal))
{
value1 = Convert.ToInt32(value1);
value2 = Convert.ToInt32(value2);
}
// debugger confirms that value1 is 0 and value2 is 0
if (value1 != value2)
{
// yet these lines are always called
Console.WriteLine("The two A's are not equal");
return false;
}
}
return true;
}
This code is intended to be written such that:
A1.MyProp A2.MyProp Equal?
---------------------------------
0.0m 0.0m Yes
0.6m 1.4m Yes
1.5m 2.5m Yes
2.5m 3.5M No
However, as demonstrated by the following console app, the first use case (0.0m and 0.0m) is always failing:
private static void Main(string[] args)
{
var b = new B() { MyProp = 0.0m };
var c = new C() { MyProp = 0.0m };
// always false
var result = Compare(b, c);
}
Can anyone lend an eye and point out the bug in the comparison code?
Aucun commentaire:
Enregistrer un commentaire