C# 否定函数<;T、 布尔>;在lambda表达式中
这会导致编译错误:C# 否定函数<;T、 布尔>;在lambda表达式中,c#,asp.net,C#,Asp.net,这会导致编译错误:无法应用!运算符到Func类型的操作数 我必须为此创建另一个表达式变量吗 somelist = somelist.Where(!expr); Func expr2=x=>x.Prop==1; 使用表达式树时,以下操作可以实现此目的: somelist = somelist.Where(value => !expr(value)); 我只是想把这个作为一个愚蠢的回答扔出去。我要明确一点:我不会这样做,我也不建议任何人这样做 我想看看是否有可能获得somelist.Wh
无法应用!运算符到Func类型的操作数
我必须为此创建另一个表达式变量吗
somelist = somelist.Where(!expr);
Func expr2=x=>x.Prop==1;
使用表达式树时,以下操作可以实现此目的:
somelist = somelist.Where(value => !expr(value));
我只是想把这个作为一个愚蠢的回答扔出去。我要明确一点:我不会这样做,我也不建议任何人这样做 我想看看是否有可能获得
somelist.Where(!expr)
语法或类似的东西
我成功了,我恨我自己
somelist = somelist.Where(expr.Not());
Negator
是真正的“魔法”发生的地方:
所以再一次。。。请不要这样做。:)一定要坚持史蒂文回答中正确/理智的做事方式
编辑:这里有一个使用表达式的实现,它在语法用法方面的工作方式完全相同。不确定它是否“正确”,并且没有针对实体框架进行测试:
somelist = someList.Where(!!expr);
somelist = someList.Where(!!!expr);
somelist = someList.Where(!!!!expr);
somelist = someList.Where(!!!!!expr);
somelist = someList.Where(!!!!!!expr); //oh my what
公共类表达式否定器
{
私人表达是表达的基础;
公共表达式否定符(表达式下的表达式)
{
this.underyingexpression=underyingexpression;
}
公共静态隐式运算符Func(ExpressionNegator neg)
{
返回neg.underyingexpression.Compile();
}
公共静态隐式运算符表达式(ExpressionNegator neg)
{
返回neg.underyingexpression;
}
公共静态表达式否定运算符!(表达式否定运算符neg)
{
var originalExpression=neg.underyingexpression;
表达式否定Expression=originalExpression.Update(
表达式.Not(原始表达式.Body),
原始压力参数);
返回新的ExpressionNegator(negatedExpression);
}
}
很抱歉再折磨你一次,因为我知道这很可能会折磨你,直到你把它也用上(我曾经在那里)。我想知道您是否可以让它也与表达式一起工作,以使它与实体框架之类的Linq2Entities提供程序一起工作。@ScottChamberlain:我可能可以用表达式来完成,但我不知道它是否会转化为实体的兼容运行时执行(我想这可能毕竟是SQL查询的一些额外的否定吗?)。也许在我的业余时间,我会尝试一下。如果您想将lambda转换为它的对立面,您只需使用变量Expression originalLambda
,Expression negatedLambda=originalLambda.Update(Expression.Not(originalLambda.Body))编写,originalLambda.参数)
@ScottChamberlain:我添加了一个带有表达式的朴素实现。我针对本地列表进行了测试,但没有针对实体框架进行测试。请随意尝试一下,让我们知道它是否有效!Jean Homeial,感谢您提供的示例代码。@ChrisSinclair:我很喜欢您的努力,也很喜欢人们用这种语言进行疯狂的欺骗。我特别尊敬您我喜欢这段代码在生产中完成,而不是!!!:P
somelist = somelist.Where(value => !expr(value));
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);
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);
}
somelist = somelist.Where(expr.Not());
var expr = N.egatable<MyClass>(x => x.Prop != 1);
somelist = someList.Where(!expr);
public static class N
{
public static Negator<T> egatable<T>(Func<T, bool> underlyingFunction)
{
return new Negator<T>(underlyingFunction);
}
}
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));
}
}
somelist = someList.Where(!!expr);
somelist = someList.Where(!!!expr);
somelist = someList.Where(!!!!expr);
somelist = someList.Where(!!!!!expr);
somelist = someList.Where(!!!!!!expr); //oh my what
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);
}
}