Implementing iComparer for custom objects after converting a Dictionary to SortedDictionary

StackOverflow https://stackoverflow.com/questions/10905115

Domanda

I'm having trouble implementing an IComparer method. Essentially, I want to compare the properties of two custom objects (the properties are of type integer).

dE is a Dictionary(Of String, customObj) prTabIndex is a property of customObj and is of type Integer (these hold true for all examples)

After some more searching I found this thread which suggested 3 things: a List approach, utilizing LINQ, and using some C# 3.0 features. However, being in vb, not sure what they best approach is.

I've tried three different ways:

...rolling my own IComparer implementation:

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


...Sorting a list (which, I think works - making this thread slightly academic).

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))


...or incorporating the lambda function directly in the conversion to the 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))

Note that VS2008 has underlined 'dE.ToDictionary...' (to the end of the line) and giving me two messages depending on where I hover my mouse:

1) "Data type(s) of the type parameter(s) in extension method 'signature' As 'signature defined in 'System.Linq.Enumerable cannot be inferred from these arguments. Specifying the data types explicitly might correct this error. Seen while hovering over "ToDictionary".

2) Nested function does not have the same signature as delegate 'signature'. Seen while hovering over anything after "ToDictionary".

Admittedly, I'm new to lambda functions.

Q1) How far off am I in each of the implementations?

Q2) Which one is the computationally least expensive? Why?

Q3) Which one is the computationally most expensive? Why?

Warm Regards,

-sf

È stato utile?

Soluzione

You can save your self casting if you implement the Generic IComparable(Of ...). I think you should also handle the possibility that the two objects are equal.

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top