【问题标题】:expr. tree: Static method requires null instance, non-static method requires non-null instance表达式。树:静态方法需要空实例,非静态方法需要非空实例
【发布时间】:2015-01-26 03:24:33
【问题描述】:

我搜索了问题,发现了一些主题,我怀疑错误原因,但我无法弄清楚。

我想构建这个表达式部分:

Function(row) groupedindexes.Select(
    Function(grpindex) row(grpindex))

我已经用这个构建了 Function(grpindex) row(grpindex) 部分:

Dim fieldselector As Expressions.LambdaExpression
fieldselector = Expression.Lambda(Expression.ArrayAccess(rowParameter, indexParameter), indexParameter)

声明如下:

Dim rowParameter = Expression.Parameter(GetType(Object()), "Row")
Dim indexParameter = Expression.Parameter(GetType(Integer), "grpindex")

现在,我想像这样构建Select 部分:

Dim outerfieldselector As Expressions.LambdaExpression
outerfieldselector = Expression.Lambda(Expression.Call(grpindexes, selectMethod, fieldselector), rowParameter)

声明如下:

Dim grpindexes As Expression = Expression.Constant(groupedindexes, GetType(System.Collections.Generic.List(Of Integer)))
Dim selectMethod = GetType(Queryable).GetMethods(BindingFlags.Public Or BindingFlags.Static).First(Function(m) m.Name = "Select").MakeGenericMethod(GetType(Object), GetType(System.Func(Of Integer, Object)))

groupedindexes 是普通的List(Of Integer)

在运行时,我在outerfieldselector=... 行收到上述错误

在我看来,它应该可以工作。我用一个参数 (fieldselector) 在 grpindexes 上调用 Select 方法。

可能是什么问题?

谢谢。

编辑:可以在此链接下载示例项目:http://www.filedropper.com/exptree

编辑二:

这里是一个简单、简短的控制台应用程序项目:

Imports System.Reflection
Imports System.Linq.Expressions
Module Module1
    Dim rowParameter = Expression.Parameter(GetType(Object()), "Row")
    Dim indexParameter = Expression.Parameter(GetType(Integer), "grpindex")
    Dim expr As Expression = Nothing
    Dim groupedindexes As New List(Of Integer)
    Dim grpindexes As Expression = Expression.Constant(groupedindexes, GetType(System.Collections.Generic.List(Of Integer)))
    Dim selectMethod = GetType(Queryable).GetMethods(BindingFlags.Public Or BindingFlags.Static).First(
        Function(m) m.Name = "Select").MakeGenericMethod(GetType(Object), GetType(System.Func(Of Integer, Object)))
    Dim fieldselector As Expressions.LambdaExpression
    Dim outerfieldselector As Expressions.LambdaExpression

    Sub Main()
        groupedindexes.Add(0)
        groupedindexes.Add(1)
        groupedindexes.Add(2)
        fieldselector = Expression.Lambda(Expression.ArrayAccess(rowParameter, indexParameter), indexParameter)
        outerfieldselector = Expression.Lambda(Expression.Call(grpindexes, selectMethod, fieldselector), rowParameter)
    End Sub
End Module

编辑 3:

我想,我在 svick 的帮助下得到了它。

Dim selectMethod = GetType(Enumerable).GetMethods(BindingFlags.Public Or BindingFlags.Static).First(Function(m) m.Name = "Select").MakeGenericMethod(GetType(Integer), GetType(Object))

【问题讨论】:

  • 什么是grpindexes?如果您提供一个简短但完整的程序来演示该问题,则会更容易为您提供帮助。 (只是一个最小的控制台应用程序。)
  • 我添加了一个简单的项目,因为在这里复制所有代码会太长。 grpindexes 表示 LINQ 查询中的分组索引。
  • 不一定是您的实际代码。只是一个简短但有代表性的程序来说明问题。
  • 这是一个示例小项目。相互联系太厉害了,所以我上传了。这正是您所描述的:演示问题的简短但有代表性的程序。还是这里不允许上传?只需运行项目并点击按钮。
  • 如果你能把它写得足够​​短以包含在你的帖子中会更好。如果你有一个按钮,这表明它是一个 GUI——这几乎肯定是在添加毫无意义的代码。控制台应用程序往往是展示问题的最简单方式。

标签: vb.net linq expression-trees


【解决方案1】:

问题在于Queryable.Select() 不是实例方法。你把它当作 VB 中的一个,但它不是,这反映在表达式树中。

所以,这条线应该是这样的:

outerfieldselector = Expression.Lambda(Expression.Call(Nothing, selectMethod, grpindexes, fieldselector), rowParameter)

即使您解决了这个问题,您的代码仍然无法正常工作。其中一些问题是:

  1. MakeGenericMethod() 需要类型参数的类型。这里是TSourceTResult,应该是IntegerObject
  2. List(Of Integer) 没有实现 IQueryable

【讨论】:

  • 我应该如何修改代码?我更改了 MakeGenericMethod 中的类型,但出现错误。即使 List(Of Integer) 没有实现 IQueryable,也可以调用 Select,因为在 LINQ 查询中是可以的。
  • 我更改了 MakeGenericMethod 中的类型,并将 Queryable 更改为 Enumerable。
  • @derstauner 是的,LINQ 在普通集合上有效,因为它们实现了IEnumerable<T>,而不是IQueryable<T>,这意味着你想要Enumerable.Select(),而不是Queryable.Select()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多