2013-03-28 92 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。這對我來說似乎是一個問題,這不適合使用當前的類設計。