Вопрос

У меня есть следующая функция, которая перебирает каталог и проверяет наличие указанной папки и файла:

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

Причина, по которой я применил этот метод, заключается в том, что я мог убедиться, что все элементы в каждом списке и переданный файл / папка были в нижнем регистре, иначе я бы сделал что-то вроде этого:

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

Мой коллега ранее упоминал мне кое-что о возможности игнорировать регистр с помощью средства сравнения.В .Contains расширение может иметь аргумент средства сравнения вместе со значением.Я немного поискал в Google и MSDN и нашел следующий сравнитель:

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

Когда дело доходит до theCompare(x.name, y.name) = 0 строка, она выдает ошибку, и это сообщение об ошибке:

At least one object must implement IComparable.

Кто-нибудь знает, что означает эта ошибка и как ее исправить?

Это было полезно?

Решение

Ну, вы могли бы реализовать средство сравнения, но в данном случае это был бы трудный путь.Вместо этого у вас есть пара других доступных вариантов.

Во-первых, вы уже можете использовать средство сравнения без учета регистра.На самом деле их есть пара.Посмотрите в своих подсказках intellisense в разделе System.StringComparer.

Во-вторых, в строках уже есть встроенный способ указать сравнение без учета регистра:

Dim s As String = "a"
Dim t As String = "A"
If s.Equals(t, StringComparison.InvariantCultureIgnoreCase) Then
   ''//...
End If

И в - третьих , это то , что любой searchPattern переданный в Directory.GetFiles() или Directory.GetDirectories() передается непосредственно в операционную систему, и Windows учитывает регистр только для имен файлов, не чувствительных к регистру.Таким образом, вы можете передать свою папку и файл в качестве шаблона поиска и выполнить поиск таким образом.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top