Реализация iComparer для пользовательских объектов после преобразования словаря в SortedDictionary

У меня проблемы с реализацией метода IComparer. По сути, я хочу сравнить свойства двух пользовательских объектов (свойства имеют тип integer).

dE - это словарь (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))


... или включение лямбда-функции непосредственно в преобразование в 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) "Тип (ы) данных параметра (ов) типа в методе расширения" подпись "Подпись As", определенная в "System.Linq.Enumerable", не может быть выведен из этих аргументов. Указание типов данных в явном виде может исправить эту ошибку. во время наведения на "ToDictionary".

2) Вложенная функция не имеет той же подписи, что и делегатская "подпись". Видно при наведении на что-либо после "ToDictionary".

Правда, я новичок в лямбда-функциях.

Q1) Как далеко я в каждой из реализаций?

Q2) Какой из них вычислительно наименее дорогой? Зачем?

Q3) Какой из них вычислительно самый дорогой? Зачем?

Теплые пожелания,

-sf

1 ответ

Решение

Вы можете сохранить свое собственное приведение, если реализуете Generic 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
Другие вопросы по тегам