Где отсутствует выражение linq
-
20-09-2019 - |
Вопрос
Я пытаюсь создать расширение "WhereNot".
Так что я могу использовать:
Dim x = "Hello world "
Dim y = x.Split.WhereNot(AddressOf String.IsNullOrEmpty)
Обратите внимание, что моя цель здесь - изучить выражения linq;не решит мою проблему.
Я создал эту функцию:
<Extension()> _
Public Function WhereNot(Of TElement)(ByVal source As IQueryable(Of TElement), ByVal selector As Expression(Of Func(Of TElement, Boolean))) As IQueryable(Of TElement)
Return source.Where(GetWhereNotExpression(selector))
End Function
Я не знаю, как переключить логический флаг, сделает ли это функция Negate?
ответы на обоих языках vb.net и C # приветствуются
Решение
Я понимаю, что это очень старый вопрос с ответом, но я думаю, что выбранный ответ вводит в заблуждение, потому что задающий искал выражение, а выбранный ответ предоставляет лямбда.
Это означает , что его вызов из IQueryable вернет IEnumerable<T>
, не являющийся IQueryable<T>
.Это вынуждает выражение компилироваться и может привести к плохо оптимизированному доступу к поставщикам Linq.
Вот ответ, который непосредственно касается первоначального вопроса.
public static class NegationExpressionHelper
{
public static IQueryable<T> WhereNot<T>(this IQueryable<T> queryable, Expression<Func<T,bool>> predicate)
{
return queryable.Where(predicate.Invert());
}
public static Expression<Func<T, bool>> Invert<T>(this Expression<Func<T, bool>> original)
{
return Expression.Lambda<Func<T, bool>>(Expression.Not(original.Body), original.Parameters.Single());
}
}
Другие советы
Да, подобный метод отрицания поможет вам:
Public Function Negate(Of T)(ByVal predicate As Func(Of T, Boolean)) As Func(Of T, Boolean)
Return Function(x) Not predicate(x)
End Function
А затем используйте его вот так:
Dim x = "Hello world "
Dim y = x.Split.Where(Negate(Of String)(AddressOf String.IsNullOrEmpty))
Или с помощью метода WhereNot(), подобного этому:
<Extension> _
Public Shared Function WhereNot(Of T)(ByVal source As IEnumerable(Of T), ByVal predicate As Func(Of T, Boolean)) As IEnumerable(Of T)
Return source.Where(Negate(predicate))
End Function