Func<T, bool> expr = x => x.Prop != 1;
somelist = somelist.Where(expr);
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.但我想这样否定expr:
somelist = somelist.Where(!expr);
Run Code Online (Sandbox Code Playgroud)
这导致编译错误:Cannot apply ! operator to operand of type Func<T, bool>.
我是否必须为此创建另一个表达式变量?
Func<T, bool> expr2 = x => x.Prop == 1;
Run Code Online (Sandbox Code Playgroud)
Ste*_*ven 52
Func<T, bool> expr = x => x.Prop != 1;
Func<T, bool> negativeExpr = value => !expr(value);
Run Code Online (Sandbox Code Playgroud)
要么
somelist = somelist.Where(value => !expr(value));
Run Code Online (Sandbox Code Playgroud)
使用表达式树时,以下方法将起到作用:
Expression<Func<T, bool>> expr = x => x.Prop != 1;
var negativeExpr = Expression.Lambda<Func<T, bool>>(
Expression.Not(expr.Body),
expr.Parameters);
somelist = somelist.Where(negativeExpr);
Run Code Online (Sandbox Code Playgroud)
为了让您的生活更轻松,您可以创建以下扩展方法:
public static Func<T, bool> Not<T>(
this Func<T, bool> predicate)
{
return value => !predicate(value);
}
public static Expression<Func<T, bool>> Not<T>(
this Expression<Func<T, bool>> expr)
{
return Expression.Lambda<Func<T, bool>>(
Expression.Not(expr.Body),
expr.Parameters);
}
Run Code Online (Sandbox Code Playgroud)
现在你可以这样做:
somelist = somelist.Where(expr.Not());
Run Code Online (Sandbox Code Playgroud)
Chr*_*air 18
我只是把它扔出去作为一个愚蠢的答案.要明确一点:我不会这样做,我不建议任何人这样做.:)
我有点想看看是否有可能获得somelist.Where(!expr)语法或类似的东西.
我成功了,我讨厌自己.
var expr = N.egatable<MyClass>(x => x.Prop != 1);
somelist = someList.Where(!expr);
Run Code Online (Sandbox Code Playgroud)
这N.egatable只是一个小的方便语法助手,并且很大程度上是不必要的(编辑:我想避免必须明确定义MyClass或以某种方式隐藏对象包装器的实例化,但是不能完全实现并认为可能有人会有更好的想法) :
public static class N
{
public static Negator<T> egatable<T>(Func<T, bool> underlyingFunction)
{
return new Negator<T>(underlyingFunction);
}
}
Run Code Online (Sandbox Code Playgroud)
Negator<T> 是真正的"魔法"发生的地方:
public class Negator<T>
{
private Func<T, bool> UnderlyingFunction;
public Negator(Func<T, bool> underlyingFunction)
{
this.UnderlyingFunction = underlyingFunction;
}
public static implicit operator Func<T, bool>(Negator<T> neg)
{
return v => neg.UnderlyingFunction(v);
}
public static Negator<T> operator !(Negator<T> neg)
{
return new Negator<T>(v => !neg.UnderlyingFunction(v));
}
}
Run Code Online (Sandbox Code Playgroud)
首先,!运算符重载执行函数否定(就像在此答案中一样),然后使用隐式转换运算符将Func<T, bool>其传递给Where扩展方法.
也许非常愚蠢的是你可以像这样来回翻转它:
somelist = someList.Where(!!expr);
somelist = someList.Where(!!!expr);
somelist = someList.Where(!!!!expr);
somelist = someList.Where(!!!!!expr);
somelist = someList.Where(!!!!!!expr); //oh my what
Run Code Online (Sandbox Code Playgroud)
所以再次......请不要这样做.:)绝对坚持正确/理智的做事方式,如史蒂文的答案.
编辑:这是一个使用表达式的实现,它在语法用法方面的工作方式完全相同.不确定它是否"正确",并且没有针对Entity Framework进行测试:
public class ExpressionNegator<T>
{
private Expression<Func<T, bool>> UnderlyingExpression;
public ExpressionNegator(Expression<Func<T, bool>> underlyingExpression)
{
this.UnderlyingExpression = underlyingExpression;
}
public static implicit operator Func<T, bool>(ExpressionNegator<T> neg)
{
return neg.UnderlyingExpression.Compile();
}
public static implicit operator Expression<Func<T, bool>>(ExpressionNegator<T> neg)
{
return neg.UnderlyingExpression;
}
public static ExpressionNegator<T> operator !(ExpressionNegator<T> neg)
{
var originalExpression = neg.UnderlyingExpression;
Expression<Func<T, bool>> negatedExpression = originalExpression.Update(
Expression.Not(originalExpression.Body),
originalExpression.Parameters);
return new ExpressionNegator<T>(negatedExpression);
}
}
Run Code Online (Sandbox Code Playgroud)