0

我在实现 IComparer 方法时遇到了麻烦。本质上,我想比较两个自定义对象的属性(属性是整数类型)。

dE 是 Dictionary(Of String, customObj) prTabIndex 是 customObj 的一个属性,并且是 Integer 类型(所有示例都适用)

经过一番搜索后,我发现这个线程建议了 3 件事:List 方法、利用 LINQ 和使用一些 C# 3.0 特性。但是,在 vb 中,不确定他们最好的方法是什么。

我尝试了三种不同的方法:

...滚动我自己的 IComparer 实现:

Public m As Sub(ByRef d As Dictionary(of String, customObj))

   Dim sortedD As New SortedDictionary(Of String, customObj)(d, myCompare)

End Sub

 Public Class myCompare
     Implements IComparer

    Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
        If TryCast(x, customObj).prTabIndex < TryCast(y, customObj).prTabIndex Then
            Return -1
        Else
            Return 1
        End If
    End Function
End Class


...对列表进行排序(我认为这是可行的——使这个线程有点学术性)。

Dim sortedL As List(Of KeyValuePair(Of String, customObj)) = dE.ToList
    sortedL.Sort(Function(firstPair As KeyValuePair(Of String, customObj), nextPair As KeyValuePair(Of String, customObj)) firstPair.Value.prTabIndex.CompareTo(nextPair.Value.prTabIndex))


...或将 lambda 函数直接合并到到 SortedDictionary 的转换中:

        Dim dESorted = From kvp As KeyValuePair(Of String, customObj) In dE.ToDictionary(Function(first As KeyValuePair(Of String, customObj), second As KeyValuePair(Of String, customObj)) first.Value.prTabIndex.CompareTo(nextPair.Value.prTabIndex))

请注意,VS2008 已在 'dE.ToDictionary...' 下划线(到行尾),并根据我将鼠标悬停的位置给我两条消息:

1)“扩展方法'签名'中类型参数的数据类型作为'System.Linq.Enumerable中定义的签名无法从这些参数中推断出来。明确指定数据类型可能会纠正此错误。看到将鼠标悬停在“ToDictionary”上。

2) 嵌套函数与委托“签名”的签名不同。在“ToDictionary”之后悬停在任何内容上时出现。

诚然,我是 lambda 函数的新手。

Q1)我在每个实现中离我有多远?

Q2) 哪一个是计算成本最低的?为什么?

Q3) 哪一个是计算上最昂贵的?为什么?

温暖的问候,

-sf

4

1 回答 1

3

如果您实现通用 IComparable(Of ...),您可以保存您的自我转换。我认为您还应该处理两个对象相等的可能性。

Public Class DemoClass
  Implements IComparable(Of DemoClass)

  Private mstrField1 As String
  Public Property Field1() As String
    Get
      Return mstrField1
    End Get
    Set(ByVal value As String)
      mstrField1 = value
    End Set
  End Property


  Private mstrField2 As String
  Public Property Field2() As String
    Get
      Return mstrField2
    End Get
    Set(ByVal value As String)
      mstrField2 = value
    End Set
  End Property

  Private mstrField3 As String
  Public Property Field3() As String
    Get
      Return mstrField3
    End Get
    Set(ByVal value As String)
      mstrField3 = value
    End Set
  End Property

  ''' <summary>
  ''' Default sort - 1 ASC, 2 ASC, 3 ASC 
  ''' </summary>
  ''' <param name="other"></param>
  ''' <returns></returns>
  ''' <remarks></remarks>
  Public Function CompareTo(ByVal other As DemoClass) As Integer Implements System.IComparable(Of DemoClass).CompareTo
    '-1 = less than other; 0 = same as other; +1 = greater than other'
    Select Case Me.Field1
      Case Is < other.Field1 : Return -1
      Case Is > other.Field1 : Return 1
      Case Else 'equal
        Select Case Me.Field2
          Case Is < other.Field2 : Return -1
          Case Is > other.Field2 : Return 1
          Case Else 'equal
            Select Case Me.Field3
              Case Is < other.Field3 : Return -1
              Case Is > other.Field3 : Return 1
              Case Else : Return 0 'equal
            End Select
        End Select
    End Select
  End Function
End Class
于 2012-06-06T03:20:43.100 回答