¿Cómo se implementa un IEqualityComparer en VB.NET?
-
06-09-2019 - |
Pregunta
Tengo la siguiente función que recorra un directorio y comprueba si hay una carpeta especificada y el archivo:
Private Function VerifyPath(ByVal root As String, ByVal folder As String, _
ByVal file As String) As Boolean
Dim folders As New List(Of String), files As New List(Of String)
Dim oDir As New IO.DirectoryInfo(root)
For Each dir As IO.DirectoryInfo In oDir.GetDirectories
folders.Add(dir.Name.ToLower)
Next
If folders.Contains(folder) Then
For Each item As IO.FileInfo In oDir.GetFiles
files.Add(item.Name.ToLower)
Next
If files.Contains(file) Then
Return True
End If
End If
Return False
End Function
La razón por la que este método es para que pudiera asegurarse de que los elementos en cada lista y el archivo / carpeta pasado eran todo en minúsculas, de lo contrario habría hecho algo como esto:
If oDir.GetDirectories.Contains( _
New IO.DirectoryInfo(String.Format("{0}\{1}", root, folder))) Then
If oDir.GetFiles.Contains( _
New IO.FileInfo(String.Format("{0}\{1}", root, file))) Then
Return True
End If
End If
Return False
Mi colega mencionado algo a mí antes de ser capaz de ignorar caso utilizando un comparador. La extensión .Contains
puede tener un argumento comparador junto con el valor. Hice algunas búsquedas en Google y MSDN, y se acercó con la siguiente comparador:
Public Class dirCompare
Implements IEqualityComparer(Of IO.DirectoryInfo)
Dim theCompare As CaseInsensitiveComparer
Sub New()
theCompare = CaseInsensitiveComparer.DefaultInvariant
End Sub
Sub New(ByVal culture As CultureInfo)
theCompare = New CaseInsensitiveComparer(culture)
End Sub
Public Function Equals1(ByVal x As System.IO.DirectoryInfo, ByVal y As System.IO.DirectoryInfo) As Boolean Implements System.Collections.Generic.IEqualityComparer(Of System.IO.DirectoryInfo).Equals
If theCompare.Compare(x.name, y.name) = 0 Then
Return True
Else
Return False
End If
End Function
Public Function GetHashCode1(ByVal obj As System.IO.DirectoryInfo) As Integer Implements System.Collections.Generic.IEqualityComparer(Of System.IO.DirectoryInfo).GetHashCode
Return obj.ToString.ToLower.GetHashCode
End Function
End Class
Cuando se llega a la línea de theCompare(x.name, y.name) = 0
, que los errores y este es el mensaje de error:
At least one object must implement IComparable.
Alguien sabe lo que significa este error y cómo hacer para corregirlo?
Solución
Bien podría implementar un comparador, pero eso sería la manera más difícil en este caso. Usted tiene un par de otras opciones disponibles en su lugar.
La primera es que ya hay un comparador entre mayúsculas y minúsculas que puede utilizar. Hay un par de hecho. Mire en sus instrucciones de IntelliSense bajo System.StringComparer
.
La segunda es que las cadenas ya tienen una forma integrada para especificar una comparación entre mayúsculas y minúsculas:
Dim s As String = "a"
Dim t As String = "A"
If s.Equals(t, StringComparison.InvariantCultureIgnoreCase) Then
''//...
End If
Y una tercera es que cualquier searchPattern
pasó a Directory.GetFiles()
o Directory.GetDirectories()
se pasa directamente al sistema operativo, y Windows es único caso-conscientes de nombres de archivo, no entre mayúsculas y minúsculas. Por lo que puede pasar su carpeta y archivo como un patrón de búsqueda y hacer su consulta de esa manera.