此功能使用气泡算法按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
答案 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
非常慢)。