2012-08-26 38 views
0

我有一個imprmented排序方法在我的代碼集合今天我注意到一些奇怪的東西。當我試圖向枚舉中添加新的枚舉值時,sort方法會因此錯誤而崩潰。排序停止工作後枚舉值添加

無法排序,因爲IComparer.Compare()方法返回不一致的結果。一個值不會與自身等同,或者一個值反覆與另一個值比較會得到不同的結果。 x:'',x的類型:'Texture2D',IComparer:'System.Array + FunctorComparer`1 [Microsoft.Xna.Framework.Graphics.Texture2D]'。

這似乎真的很奇怪,現在這種方式依賴於早期的結果,它應該做的就是排序後確定alfabatic命令的枚舉索引。

這是代碼。

availableTiles.Sort(CompareTilesToEnum); 

    private static int CompareTilesToEnum(Texture2D x, Texture2D y) 
    { 
     int xValue = (int) (Enum.Parse(typeof(TileTyp), x.Name, true)); 
     int yValue = (int) (Enum.Parse(typeof(TileTyp), y.Name, true)); 
     if (xValue > yValue) 
     { 
      return 1; 
     } 
     else 
     { 
      return -1; 
     } 
    } 

    public enum TileTyp 
    { 
     Nothing = -1, 
     Forest, 
     Grass, 
     GrassSandBottom, 
     GrassSandLeft, 
     GrassSandRight, 
     GrassSandTop, 
     Mounten, 
     Sand, 
     Snow, 
     Water, 
     GrassSandTopLeft, 
     GrassSandAll, 
     GrassSandBottomLeft, 
     GrassSandBottomRightLeft, 
     GrassSandBottomRightTop, 
     GrassSandBottomTopLeft, 
     GrassSandRightLeft, 
     GrassSandRightTop, 
     GrassSandRightTopLeft, 
     GrassSandBottomRight, 
     GrassSandBottomTop 
    } 

我增加值是

GrassSandBottomRight, 
    GrassSandBottomTop 
+0

如果A和B相等,則對於'A> B'和'B> A',您的代碼都返回-1' –

回答

4

您的比較從不返回0 - 即使值相等。任何原因,你不只是要求int.CompareTo比較值?

private static int CompareTilesToEnum(Texture2D x, Texture2D y) 
{ 
    int xValue = (int) (Enum.Parse(typeof(TileTyp), x.Name, true)); 
    int yValue = (int) (Enum.Parse(typeof(TileTyp), y.Name, true)); 
    return xValue.CompareTo(yValue); 
} 

更簡單,更重要的是,它實際上應該工作 :)

+0

除非在集合中可能存在空'Texture2D'排序,會拋出'NullReferenceException'。 –

1

正如錯誤中明確規定,你的比較器壞了。如果值相等,則需要返回0

1

有必須與任何比較法遵循的一些規則:

  1. 如果A == B,那麼B == A(兩次都返回零)。
  2. 如果A < B和B < C,則A < C.
  3. 如果A < B,則B> A
  4. A == A(返回零如果與本身相比)。

(注意,該==上述表示幽冥<也不>是真的。這是permissable兩個對象沒有一個相應的Equals是真正處於排序順序等同。我們可以例如有一個規則按數字順序對所有包含數字的字符串進行排序,放入所有其他字符串並結束,但不關心其他字符串以什麼順序排列)。

這些規則遵循任何語言(他們沒有編程規則,他們的邏輯規則),有一個.NET特定一個太:

5:如果A = null,則A>空。

你打破了前四條規則。由於Texture2D是引用類型,因此您也有可能違反規則5(儘管會引發其他異常)。

你也很幸運,.NET捕捉到它。一個不同的排序算法可能已經崩潰了一個更令人困惑的錯誤或陷入無限循環,因爲它例如發現項目6被報告爲大於項目7並且交換它們,然後很快在發現項目6被報告爲大於項目7並交換它們,然後很快發現後...

private static int CompareTilesToEnum(Texture2D x, Texture2D y) 
{ 
    //Let's deal with nulls first 
    if(ReferenceEquals(x, y))//both null or both same item 
     return 0; 
    if(x == null) 
     return -1; 
    if(y == null) 
     return 1; 
    //Enum has a CompareTo that works on integral value, so why not just use that? 
    return Enum.Parse(typeof(TileTyp), x.Name, true)).CompareTo(Enum.Parse(typeof(TileTyp), y.Name, true))); 
} 

(這假定解析失敗是不可能的,不必考慮)。