我想从清单中选择一列IEnumerable
有在运行时只知道我一个类型的集合。 我能想到用这个唯一的办法是使用LINQ表达式来构建一个动态调用Queryable.Select
。 但是,我有一个很大的麻烦找出正确的语法来做到这一点。
我会怎么做这在明知一切,我需要在编译时的慵世界的例子,我的代码是这样的:
' Create an IEnumerable(Of String)
Dim strings = { "one", "two", "three" }
' Produce a collection with elements {3,3,5}
Dim stringLengths = strings.Select(Function(x) x.Length)
不幸的是,在现实中,我不知道该集合我已经是类型的String
,或者说我要选择的属性是Length
。 我所拥有的是一个IEnumerable
物品收集,以及一个PropertyInfo
,我要选择哪一个为我提供了所有我需要的类型的信息之列。
至于表情走了,我已经能够创建一个LINQ的表达,我认为将代表拉姆达我通常会通过选择(假设我试图执行上述同样的操作,有字符串和string.length减)
' pi is the PropertyInfo containing the Length property I am trying to select.
' pi.DeclaringType is String and pi.Name is Length
Dim targetItem = Expression.Parameter(pi.DeclaringType, "x")
Dim targetProperty = Expression.Property(targetItem, pi.Name)
' Produces the lambda<Function(x) x.Length>
Dim selectLambda = Expression.Lambda(targetProperty, targetItem)
现在希望所有剩下的就是建立是调用Queryable.Select
。 对我来说,Expression.Call的语法是非常混乱的,至少可以说。 我尝试如下(其中失败,没有任何错误或任何形式的说明):
' Creates a Parameter Expression of type IQueryable(Of String)
Dim source = Expression.Parameter(GetType(IQueryable(Of )).MakeGenericType(pi.DeclaringType), "source")
' Ideally, this would create an expression for a call to Queryable.Select
Dim selectCall = Expression.Call(GetType(Queryable), "Select", {pi.DeclaringType, pi.PropertyType}, source)
我试着不使用类型[]参数,并使用我的项目和财产无济于事表达以另一种方式这样做:
Dim alternateExp = Expression.Call(GetType(Queryable), "Select", Nothing, {targetProperty, item})
问题是,我在这一点上非常简单,只是猜测。 然而,建立函数调用,何时使用类型或表达式,使用哪种类型或表达式,或者甚至使用它们的整体思路是非常混乱。 任何让我的方式最后部分有和清除一些这奥秘的帮助,将不胜感激。 (我完全满意,在C#中的例子)