Как создать дерево выражений NotStartsWith

Я использую jqGrid для отображения некоторых данных пользователям. jqGrid имеет функцию поиска, которая сравнивает строки, такие как Equals, NotEquals, Contains, StartsWith, NotStartsWith и т. д.

Когда я использую StartsWith, я получаю действительные результаты (выглядит так):

Expression condition = Expression.Call(memberAccess,
                typeof(string).GetMethod("StartsWith"),
                Expression.Constant(value));

Поскольку DoesNotStartWith не существует, я создал его:

public static bool NotStartsWith(this string s, string value)
{
    return !s.StartsWith(value);
}

Это работает, и я могу создать строку и вызвать этот метод следующим образом:

string myStr = "Hello World";
bool startsWith = myStr.NotStartsWith("Hello"); // false

Итак, теперь я могу создать/вызвать выражение следующим образом:

Expression condition = Expression.Call(memberAccess,
                typeof(string).GetMethod("NotStartsWith"),
                Expression.Constant(value));

Но я получаю ошибку ArgumentNullException was unhandled by user code: Value cannot be null. Parameter name: method.

Кто-нибудь знает, почему это не работает или лучший способ приблизиться к этому?


person Darcy    schedule 15.08.2011    source источник


Ответы (2)


Вы проверяете метод NotStartsWith в несуществующей строке типа. Вместо typeof(string) попробуйте typeof(ExtensionMethodClass), используя класс, в который вы поместили свой метод расширения NotStartsWith. Методы расширения фактически не существуют для самого типа, они просто действуют так, как они.

Изменить: также измените порядок вызова Expression.Call следующим образом:

Expression condition = Expression.Call(
            typeof(string).GetMethod("NotStartsWith"),
            memberAccess,
            Expression.Constant(value));

Используемая вами перегрузка ожидает метод экземпляра, эта перегрузка ожидает статический метод на основе сообщения SO, на которое вы ссылались. См. здесь, http://msdn.microsoft.com/en-us/library/dd324092.aspx

person Kratz    schedule 15.08.2011
comment
Я изменил typeof(string) на typeof(MyExtensionClass), но получаю новую ошибку Static method requires null instance, non-static method requires non-null instance. Parameter name: instance. Это было задано в другом потоке stackoverflow.com/questions/3695235/expression-equals/ но я не знаю, как решить эту проблему. - person Darcy; 15.08.2011
comment
Глядя на этот пост, Expression.Call ищет первый аргумент, который вы отправляете, для передаваемой информации о методе, который не будет работать, потому что это статический метод (не экземпляр). Вы должны использовать другую перегрузку Expression.Call, например эту, msdn.microsoft. com/en-us/library/dd324092.aspx. Сначала укажите информацию о методе, а затем два аргумента. - person Kratz; 15.08.2011
comment
Спасибо за пример кода, который вы предоставили Kratz! NotStartsWith теперь отлично работает. Я очень ценю помощь. - person Darcy; 15.08.2011

я знаю, что на вопрос был дан ответ, но доступен и простой другой подход:

Expression condition = Expression.Call(memberAccess,
                                       typeof(string).GetMethod("StartsWith"),
                                       Expression.Constant(value));

condition = Expression.Not(condition);

и... готово! просто нужно отрицать выражение.

person Gabriel    schedule 19.08.2012