ERROR Статический метод требует нулевого экземпляра, нестатический метод требует непустого экземпляра

c#-4.0 expression-trees lambda linq static-methods

Вопрос

Я пытаюсь создать дерево выражений. Мне нужно прочитать данные из таблицы данных и проверить ее столбцы. Проверяемые столбцы, а также количество проверяемых столбцов известны только во время выполнения. Имена столбцов даются мне как строковый массив, и каждый столбец имеет список строк, подлежащих проверке. Я опробовал образцы деревьев выражений, как показано ниже.

Здесь я сталкиваюсь с ошибкой.

Статический метод требует нулевого экземпляра, для нестатического метода требуется непустой экземпляр. Имя параметра: экземпляр

на линии

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 }));

Принятый ответ

Это означает, что вызов метода, который вы пытаетесь представить, является статическим, но вы даете ему целевое выражение. Это похоже на попытку позвонить:

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

Вы как раз пытаетесь сделать это в форме дерева выражений, что тоже недопустимо.

Похоже, что это происходит для метода расширения Field в DataRowExtensions - поэтому «цель» метода расширения должна быть выражена в качестве первого аргумента для вызова, потому что вы действительно хотите вызвать:

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

Итак, вы хотите:

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

Это вызовет эту перегрузку, которая является способом вызова статического метода с двумя аргументами.



Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow