2016-09-18 29 views
1

我有一个名为SaveFile的自定义类。它有一个属性是SaveNumber,我试图按该属性对列表进行排序。我在这里读了一大堆文章,并将其正确排序,但它提前停止?我注意到这种情况是有79次保存的情况。它将分类:1,2,3,4,5,6,7,10,11,... 30,8,31,... 70,9,71,..我使用的代码是排序列表(Of T)提前停止

saveList.Sort(Function(x, y) x.CompareTo(y)

但是,如果我使用的代码:

For i = 0 To 3 
    saveList.Sort(Function(x, y) x.CompareTo(y)) 
Next 

然后排序正确的,但它需要一个很长的时间,一组拥有超过700 SaveFiles于它,所以它需要近5分钟,我的计划加载。有任何想法吗?

这是我为我的CompareTo函数的代码:

Public Function CompareTo(y As SaveFile) As Integer Implements IComparable(Of SaveFile).CompareTo 



    'If neither are an autosave then compare save number 
    If Not Me.Text.StartsWith("autosave") And Not y.Text.StartsWith("autosave") Then 

     If Me.SaveNumber.ToString.Length > y.SaveNumber.ToString.Length Then 
      Return False 
     ElseIf Me.SaveNumber.ToString.Length < y.SaveNumber.ToString.Length Then 
      Return True 
     End If 

     Return Me.SaveNumber < y.SaveNumber 
     'if either is an autosave 
    Else 
     'Create to comparable integers with 
     'a value of 4. We set the value to 
     '4 because it is higher than the 3 
     'available autosaves, making it sort 
     'after any autosaves if only one is 
     'an autosave. 
     Dim xComp As Integer = 4 
     Dim yComp As Integer = 4 

     'If x is an autosave then figure out 
     'which autosave number it is. 
     If Me.Text.StartsWith("autosave") Then 
      Select Case True 
       Case Me.Text.EndsWith("1") 
        xComp = 1 
       Case Me.Text.EndsWith("2") 
        xComp = 2 
       Case Me.Text.EndsWith("3") 
        xComp = 3 
      End Select 
     End If 

     'if y is an autosave then figure out 
     'which autosave number it Is. 
     If y.Text.StartsWith("autosave") Then 
      Select Case True 
       Case y.Text.EndsWith("1") 
        yComp = 1 
       Case y.Text.EndsWith("2") 
        yComp = 2 
       Case y.Text.EndsWith("3") 
        yComp = 3 
      End Select 
     End If 

     Return xComp < yComp 
    End If 
End Function 

回答

0

首先,要求2个问题一个帖子是不是一个好主意,因为它减少的机会会有人知道答案两者。例如,没有看到加载这些东西的代码,甚至不知道它们是什么,这只是一个猜测,为什么加载这么长时间。

对于排序,您的CompareTo方法有缺陷。从MSDN

比较当前实例具有相同类型的另一个对象,并返回一个整数,指示当前实例是否之前,如下,或发生在排序顺序与其他对象的相同位置。

也就是说,它应该返回-1(之前),1(之后)或0(相同)。你只是返回布尔:

If Me.SaveNumber.ToString.Length > y.SaveNumber.ToString.Length Then 
    Return False 
ElseIf Me.SaveNumber.ToString.Length < y.SaveNumber.ToString.Length Then 
    Return True 
End If 
... 
Return xComp < yComp 

我们不知道是什么类型是,但如果是上午整数,比较字符串形式的长度,如果它是不一样的比较

' Me vs Other 
Return "9".Length < "7".Length 

这将返回False(0)当它的值,它应该返回1。打开Option Strict会标记不正确的返回类型,这可能导致您找到答案。它应该是这样的,忽略了“自动”逻辑:

Public Function CompareTo(other As SaveItem) As Integer _ 
        Implements IComparable(Of SaveItem).CompareTo 

    ... special handling for "auto" 

    If Me.SaveNumber = other.SaveNumber Then 
     Return 0 
    ElseIf Me.SaveNumber < other.SaveNumber Then 
     Return -1 
    Else 
     Return 1 
    End If 

End Function 

但是,你可能甚至不需要说(再次证明是一个int假设):

saveItems = saveItems.OrderBy(Function(q) q.SaveNumber).ToList() 

IComparable.CompareTo()可能需要以处理“自动保存”逻辑,但可能会在OrderBy()中处理,具体取决于该类所公开的信息。

+0

这实际上非常有帮助。长度比较是因为我厌倦了19和20之间的2人。谢谢你解释CompareTo。我一直在试图理解它,而我发现的例子像我的那样返回布尔值。我在编写这个程序时有点学习,现在我觉得我明白了很多。非常感谢! –

+0

哦,我忘了说,我必须做CompareTo(据我所知),因为自动保存绝对必须在顶部。 –

+0

如果2出现在19和20之间,那么你正在排序数字的形式。因为每个[ascii值](http://www.asciitable.com/)为2> 1,因此''2“'超过'”19“''。你可以使用自然排序,但我怀疑“自动”的东西不会出来,因为你想。 AutoSaves could可能会使用orderby来完成,但比较器方法(不必是IComparable)可以创建更整洁的代码。 – Plutonix