2013-03-28 126 views
1

我想要有表达式类来比较两个对象并通过下面的测试。使用IComparable接口比较int和long

public abstract class ComparisonExpression 
{ 
    public bool Evaluate(IComparable left, object right) 
    { 
     if (left == null && right == null) 
      return true; 

     if (left == null || right == null) 
      return false; 

     return GetResult(left.CompareTo(right)); 
    } 

    protected abstract bool GetResult(int comparisonResult); 
} 

public class AreEqualExpression : ComparisonExpression 
{ 
    protected override bool GetResult(int comparisonResult) 
    { 
     return comparisonResult == 0; 
    } 
} 

// TEST 

const int i = 123; 
const long l = 123L; 
const string s = "123"; 

Assert.IsTrue(new AreEqualExpression().Evaluate(i, l)); 
Assert.IsFalse(new AreEqualExpression().Evaluate(i, s)); 
Assert.IsFalse(new AreEqualExpression().Evaluate(l, s)); 

看起来好像IComparable实现期望给定类型匹配当前类型。我有一个异常,如“对象必须是Int32类型”。

我以为如果类型不相等返回false。它可以防止发生异常,但它可以制止我想要的行为。

另外我想过一个类型转换,但这次字符串和int比较将返回true,我不想要。

有什么建议吗?

+0

只是为了检查我是否正确理解:您希望比较器像往常一样进行比较,除非这两种类型都是“数字”。在这种情况下,您希望比较器检查数字是否具有相同的值。如果这就是你所要求的:这只适用于整数类型(字节,短,...)还是小数和浮点数? – bigge 2013-03-28 08:27:25

+0

不,这应该处理任何实现IComparable的类型。我的解决方案是比较之前我检查两个值是否是数字。如果是这样,那么我将这两个值转换为十进制,然后进行比较。但它仍然是双层和浮动的越野车。 – 2013-03-28 09:01:17

+0

这就是我所理解的。所以,粗略地说,你的算法应该做到以下几点? a)如果两者都是浮点数(float,double) - >使用浮点值进行比较b)如果两者都是整数值(short,int,long,...) - >比较整数值c)否则,照常进行比较。那是对的吗? – bigge 2013-03-28 13:10:49

回答

0

如果你定义了这个辅助类

public static class NumericalHelper { 
    public static double AsDouble(this object value, out bool success) { 
     if (value is sbyte || value is byte || value is short || value is ushort || value is int || value is uint || value is long || value is decimal || value is ulong || value is float || value is double || value.GetType().IsEnum) { 
      success = true; 
      return Convert.ToDouble(value); 
     } 
     success = false; 
     return 0; 
    } 
} 

你可以做这样的比较:

public bool Evaluate(IComparable left, object right) { 
    if (left == null && right == null) 
     return true; 

    if (left == null || right == null) 
     return false; 

    bool isNumerical; 
    double leftValue = left.AsDouble(out isNumerical); 
    double rightValue = isNumerical ? right.AsDouble(out isNumerical) : 0; 

    if (isNumerical) 
     return GetResult(Comparer<Double>.Default.Compare(leftValue, rightValue)); 
    else { 
     if (left.GetType() == right.GetType()) 
      return GetResult(left.CompareTo(right)); 
     else 
      return false; 
} 

但要注意平等是usully与Equals方法或与IEquatable接口相比, ,在你的例子中根本不考虑。 Here is more information about implementing equality。这对我来说似乎是一个问题,这不适合使用当前的类设计。