将IO.DirectoryInfo属性作为参数传递给函数?

时间:2013-09-29 17:22:57

标签: .net vb.net linq list directoryinfo

此功能使用气泡算法按IO.DirectoryInfo属性对Name列表进行排序。

如何在参数中指定我将对列表进行排序的属性?

例如:“Drive”,“Name”,“Name.Length”,“Directory.Parent”等......

我认为这是一个好主意(可能不好,我不知道可以改进多少)是将参数作为字符串传递然后将字符串转换为...?这是我迷失的地方。

Public Shared Function BubbleSort_List(list As List(Of IO.DirectoryInfo), ByVal SortByProperty As ...) As List(Of IO.DirectoryInfo)
    Return list.Select(Function(s) New With { _
        Key .OrgStr = s, _
        Key .SortStr = System.Text.RegularExpressions.Regex.Replace( _
                       s.Name, "(\d+)|(\D+)", _
                       Function(m) m.Value.PadLeft(list.Select(Function(folder) folder.Name.Length).Max, _
                       If(Char.IsDigit(m.Value(0)), " "c, Char.MaxValue))) _
    }).OrderBy(Function(x) x.SortStr).Select(Function(x) x.OrgStr).ToList

End Function

更新

请注意上面代码的这一部分:

list.Select(Function(folder) folder.Name.Length).Max

我需要的是调用函数指定我想要的属性而不是“Name”属性。

  

更新2

尝试使用@Sriram Sakthivel解决方案,但它会在[property]变量上抛出一个异常,说明UnaryExpression与MemberExpression之间不兼容的转换。

    Imports System.Reflection
    Imports System.Linq.Expressions


Private Sub Test(sender As Object, e As EventArgs) Handles MyBase.Shown

    ' Here I create the list
    Dim Folders As List(Of IO.DirectoryInfo) = _
        IO.Directory.GetDirectories("E:\Música\Canciones", "*", IO.SearchOption.TopDirectoryOnly) _
        .Select(Function(p) New IO.DirectoryInfo(p)).ToList()

    ' Here I try to loop the list at the same time I try to sort it, 
    ' specifying the property I want using @Sriram Sakthivel solution,
    ' This part does not work because the second parametter is wrong.
    For Each folderinfo In BubbleSort_List(Folders, Function() Name)
        MsgBox(folderinfo.Name)
    Next

End Sub


    Private Function BubbleSort_List(list As List(Of IO.DirectoryInfo), exp As Expression(Of Func(Of Object))) As List(Of IO.DirectoryInfo)

        Dim [property] As PropertyInfo = DirectCast(DirectCast(exp.Body, MemberExpression).Member, PropertyInfo)

        Return list.Select(Function(s) New With { _
            Key .OrgStr = s, _
            Key .SortStr = System.Text.RegularExpressions.Regex.Replace( _
                           s.Name, "(\d+)|(\D+)", _
                           Function(m) m.Value.PadLeft(list.Select(Function(folder) DirectCast([property].GetValue(folder, Nothing), String).Length).Max(), _
                           If(Char.IsDigit(m.Value(0)), " "c, Char.MaxValue))) _
        }).OrderBy(Function(x) x.SortStr).Select(Function(x) x.OrgStr).ToList

    End Function

2 个答案:

答案 0 :(得分:1)

您可以使用MemberExpression执行单个级别的属性。 obj.Prop.Prop2需要使用UnaryExpression

Private Shared Sub DoSomething(list As List(Of DirectoryInfo), exp As Expression(Of Func(Of Object)))
    Dim member As MemberExpression

    If (TypeOf exp.Body Is UnaryExpression) Then
        member = DirectCast(DirectCast(exp.Body, UnaryExpression).Operand, MemberExpression)
    Else
        member = DirectCast(exp.Body, MemberExpression)
    End If

    Dim [property] As PropertyInfo = DirectCast(member.Member, PropertyInfo)

'You could then use it like
list.Select(Function(folder) DirectCast([property].GetValue(folder, Nothing), String).Length).Max()
End Sub

Private Shared Sub Main()
Dim dir = New DirectoryInfo("somedirectory")
DoSomething(list, Function() dir.Parent)
    DoSomething(list, Function() dir.Name)
    DoSomething(list, Function() dir.FullName)

    DoSomething(list, Function() dir.Parent.Name)'Requires additional effort
End Sub

可能是语法错误。我基本上是c#程序员。我刚用Vb.net的转换工具

编辑:

由于你有目录列表,你怀疑如何传递dir.Name参数实际上并不重要,dir.Name只是传递给它的PropertyInfo

所以你可以简单地通过New DirectoryInfo("somedirectory").Name。请尝试以下

Dim dir = New DirectoryInfo("SomeArbitaryStringIsEnough")

For Each folderinfo In BubbleSort_List(Folders, Function() dir.Name)
    MsgBox(folderinfo.Name)
Next

答案 1 :(得分:0)

如果我理解了你想要的东西,那么Sriram Sakthivel代码会设置所需内容的一部分,但无法提供你想要的东西。

For Each folderinfo In BubbleSort_List(Folders, "Name")
    MsgBox(folderinfo.Name)
Next

您必须使用目标属性的名称(“Name”,“CreationTime”等)设置字符串类型参数,并从其中一个列表项(例如,第一个)中检索此属性通过GetProperty;请记住,LINQ查询是指项目,而不是整个列表。

Private Function BubbleSort_List(list As List(Of IO.DirectoryInfo), propName As String) As List(Of IO.DirectoryInfo)

    Dim curProperty As PropertyInfo = list(0).GetType().GetProperty(propName)

    Return list.Select(Function(s) New With { _
        Key .OrgStr = s, _
        Key .SortStr = System.Text.RegularExpressions.Regex.Replace( _
                       s.Name, "(\d+)|(\D+)", _
                       Function(m) m.Value.PadLeft(list.Select(Function(folder) DirectCast(curProperty.GetValue(folder, Nothing), String).Length).Max(), _
                       If(Char.IsDigit(m.Value(0)), " "c, Char.MaxValue))) _
    }).OrderBy(Function(x) x.SortStr).Select(Function(x) x.OrgStr).ToList

End Function

注意:我只是建议更正您的代码,以便您了解我想要的内容。我不建议默认依赖Reflection.GetValue非常慢)。