【问题标题】:ERROR Static method requires null instance, non-static method requires non-null instance错误静态方法需要空实例,非静态方法需要非空实例
【发布时间】:2011-10-22 04:43:48
【问题描述】:

我正在尝试创建一个表达式树。我需要从数据表中读取数据并检查其列。要检查的列以及要检查的列数仅在运行时是已知的。列名作为字符串数组提供给我,并且每列都有一个要检查的字符串列表。我尝试了示例表达式树,如下所示。

这里我遇到了一个错误。

静态方法需要空实例,非静态方法需要非空实例。 参数名称:实例

在线上

inner = Expression.Call(rowexp,mi, colexp);

请帮帮我!!!

IQueryable<DataRow> queryableData = CapacityTable
    .AsEnumerable()
    .AsQueryable()
    .Where(row2 => values.Contains(row2.Field<string>("Head1").ToString()) 
                && values.Contains(row2.Field<string>("Head2").ToString()));

MethodInfo mi = typeof(DataRowExtensions).GetMethod(
     "Field", 
      new Type[] { typeof(DataRow),typeof(string) });

mi = mi.MakeGenericMethod(typeof(string));

ParameterExpression rowexp = Expression.Parameter(typeof(DataRow), "row");
ParameterExpression valuesexp = Expression.Parameter(typeof(List<string>), "values");
ParameterExpression fexp = Expression.Parameter(typeof(List<string>), "types");
Expression inner, outer, predicateBody = null;

foreach (var col in types)
{
    // DataRow row = CapacityTable.Rows[1];

    ParameterExpression colexp = Expression.Parameter(typeof(string), "col");
    //  Expression left = Expression.Call(pe, typeof(string).GetMethod("ToLower", System.Type.EmptyTypes));

    inner = Expression.Call(rowexp,mi, colexp);
    outer = Expression.Call(valuesexp, typeof(List<string>).GetMethod("Contains"), inner);
    predicateBody = Expression.And(predicateBody,outer);
}

MethodCallExpression whereCallExpression = Expression.Call(
    typeof(Queryable),
    "Where",
    new Type[] { queryableData.ElementType },
    queryableData.Expression,
    Expression.Lambda<Func<DataRow,bool>>(predicateBody, new ParameterExpression[] { rowexp }));

【问题讨论】:

    标签: linq c#-4.0 lambda expression-trees static-methods


    【解决方案1】:

    这意味着您尝试表示的方法调用是静态的,但您正在给它一个目标表达式。这就像尝试调用:

    Thread t = new Thread(...);
    // Invalid!
    t.Sleep(1000);
    

    你试图以表达式树的形式这样做,这也是不允许的。

    DataRowExtensions 上的 Field 扩展方法似乎正在发生这种情况 - 所以扩展方法的“目标”需要表示为调用的第一个 参数,因为你真的想打电话:

    DataRowExtensions.Field<T>(row, col);
    

    所以你想要:

    inner = Expression.Call(mi, rowexp, colexp);
    

    这将调用this overload,这是调用带有两个参数的静态方法的方式。

    【讨论】:

    • 您能否详细说明以上内容?为什么在这里将 Method 信息作为第一个参数传递给 Expression.Call 方法?
    • @Kobojunkie:因为这就是你告诉Expression.Call我们感兴趣的静态方法的方式。见msdn.microsoft.com/en-us/library/bb301084.aspx
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多