Реализация 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