创建一个评估为

时间:2016-03-09 16:03:11

标签: c# c#-4.0

我目前正在上课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#中是否可以解决?或者我是否在编程语言中达到了极限?

1 个答案:

答案 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!