我目前正在上课RoundedDouble
。本课程的目的是提供.Net双结构的替代方案。它应该与double类似,但是舍入到多个小数位。首先,我们只想在用户界面级别设置格式化数字,但我们仍然需要确保用户界面中显示的值是计算中使用的值(有限的精度)双被接受)。这意味着舍入到2位小数并输入为1.23456789的值应该计算为1.23。
(我们已经考虑使用自定义TypeConverter
作为替代方案,但我们选择了RoundedDouble
,因为我们可以使用算术来保留最低精度,类似于使用数字计算和取它们的重要性/准确性考虑在内。)
现在我已为IEquatable<Double>
课程实施了RoundedDouble
,并且我遇到了以下情况:
object roundedDoubleBoxedAsObject = new RoundedDouble(2, 1.23456789); //1st param is the number of decimal places
double expectedValue = 1.23;
Debug.Assert(Equals(roundedDoubleBoxedAsObject, expectedValue)); // Passes, as RoundedDouble.Equals(double) is called
Debug.Assert(Equals(expectedValue, roundedDoubleBoxedAsObject),
"Rounded value should be considered equal."); // <-- Fails, because Double.Equals(object) is called!
我已经实现了从RoundedDouble到Double的隐式转换,这已经涵盖了很多问题。但是当RoundedDouble被装箱作为对象时,隐含的转换就被规避了。
这个问题在C#中是否可以解决?或者我是否在编程语言中达到了极限?
答案 0 :(得分:0)
似乎盒装比较的问题已经成为C#v4.0中的一个挑战,因为使用System.Object.Equals(Object)将不会像你预期的那样工作:
double oneAsDouble = 1.0;
int oneAsInteger = 1;
Debug.Assert(oneAsDouble.Equals(oneAsInteger)); // Pass
Debug.Assert(oneAsInteger.Equals(oneAsDouble)); // Pass
Debug.Assert(Equals((object)oneAsDouble, (object)oneAsInteger)); // <-- Fails!
Debug.Assert(oneAsDouble.Equals((object)OneAsInteger)); // <-- Fails!
Debug.Assert(oneAsInteger.Equals((object)oneAsDouble)); // <-- Fails!