2010-09-21 63 views
2

我想在运行时使用反射来比较两个值。我为此使用了Comparer.Default.Compare(x,y),但我意识到这是不够的。假设我想比较一个double(1.0 == 10)。 Comparer.Default会抛出一个异常,因为它坚持这两个值必须是相同的类型(double)。然而,这个存在明确的转换,这真的是我想要使用的。使用反射的比较运算符

那么,为什么我不能只使用Convert.ChangeType?以1.25> 1(double> integer)的情况。如果我尝试1.25上的Convert.ChangeType(1.25,typeof(int)),我会得到1,并且上面的断言将失败,当真正的1.25 IS> 1时。

那么,有人可以请建议一种调用显式比较(如果存在)类型定义?

谢谢。

回答

5

你使用的是C#4和.NET 4吗?如果是这样,使用动态类型非常简单:

dynamic x = firstValue; 
dynamic y = secondValue; 
if (x > y) // Or whatever 

编译器会为您执行所有适当的转换。

+0

不错的选择!我总是忘记为此使用动态。 – 2010-09-21 15:37:38

+0

我可以用表情树做这个吗? (.NET 2.0 + DLR是我的选择,但4.0不是)我试图发射一个快速调用,执行基本拉姆达比较Expression.Convert(Expression.Parameter(typeof(single)),typeof(double))在我的单个值上,但是在执行时失败并且在执行时(无法编译时)无效。我本来可以做错的事情,因为我只花了大约5分钟的时间尝试这个,然后不得不吃完午饭...... – Jeff 2010-09-21 21:17:40

+0

@ JeffN825:我认为你需要为自己制定正确的转换。这不会很有趣。 – 2010-09-21 22:25:57

1

如果C#4是一个选项,Jon Skeet's suggestion of using dynamic是最有可能的理想选择。

如果不是,则...

没有明确的比较。编译器在编译时进行转换,然后调用适当的比较。

最好的办法是使用Convert.ChangeType转换为更宽的类型,然后对结果进行比较。如果您不想处理所有类型的检查,则通常可以将双方转换为decimal值,然后使用单个比较来检查它们,因为decimal应该充分处理所有值。

+0

谢谢......但我如何确定“更宽”的类型? – Jeff 2010-09-21 18:20:57

+0

@ JeffN825:你必须手动检查它 - 这就是为什么我建议使用小数(因为它总是宽/宽)。 – 2010-09-21 18:48:08

+0

双数的最大值/最小值小于小数的情况如何? – Jeff 2010-09-21 19:02:30