Como você implementar um IEqualityComparer em VB.NET?
-
06-09-2019 - |
Pergunta
Eu tenho a seguinte função que percorre um diretório e verifica a existência de uma pasta especificada e file:
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
A razão que eu fiz este método é para que eu pudesse ter certeza de que os itens em cada lista e o arquivo / pasta passado eram todas as letras minúsculas, caso contrário eu teria feito algo como isto:
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
O meu colega mencionou algo para mim antes de ser capaz de ignorar caso usando um comparador. A extensão .Contains
pode ter um argumento comparer juntamente com o valor. Eu fiz alguma pesquisa no google e MSDN, e veio com o seguinte comparer:
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
Quando se chega à linha theCompare(x.name, y.name) = 0
, ele erros fora e esta é a mensagem de erro:
At least one object must implement IComparable.
Qualquer um sabe o que significa esse erro e como proceder para corrigi-lo?
Solução
Bem, você poderia implementar um comparador, mas que seria a maneira mais difícil neste caso. Você tem algumas outras opções disponíveis em seu lugar.
A primeira é que já existe um comparador de maiúsculas e minúsculas, você pode usar. Há um par de fato. Olhar em seus prompts intellisense sob System.StringComparer
.
O segundo é que as cordas já tem um built-in maneira de especificar um case-insensitive comparar:
Dim s As String = "a"
Dim t As String = "A"
If s.Equals(t, StringComparison.InvariantCultureIgnoreCase) Then
''//...
End If
E um terceiro é que qualquer searchPattern
passado para Directory.GetFiles()
ou Directory.GetDirectories()
é passado diretamente para o sistema operacional e Windows só é caso-aware para nomes de arquivos, não diferencia maiúsculas de minúsculas. Então você pode passar sua pasta e arquivo como um padrão de pesquisa e fazer sua pesquisa dessa forma.