Negating Func<T, bool> in lambda expression [duplicate] - c#

This question already has answers here:
Is there any way to negate a Predicate?
(2 answers)
Closed 9 years ago.
Func<T, bool> expr = x => x.Prop != 1;
somelist = somelist.Where(expr);
So far so good. But I would like to negate expr like this:
somelist = somelist.Where(!expr);
Which result in a compile error: Cannot apply ! operator to operand of type Func<T, bool>.
Do I have to create another expression variable for this?
Func<T, bool> expr2 = x => x.Prop == 1;

Func<T, bool> expr = x => x.Prop != 1;
Func<T, bool> negativeExpr = value => !expr(value);
or
somelist = somelist.Where(value => !expr(value));
When using expression trees the following will do the trick:
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);
To make your life easier, you can create the following extension methods:
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);
}
Now you can do this:
somelist = somelist.Where(expr.Not());

I'm just going to throw this out there as a silly answer. Just to be clear: I would not do this, and I do not recommend that anyone does this. :)
I kind of wanted to see if it was possible to get the somelist.Where(!expr) syntax or something like it.
Well I succeeded, and I hate myself.
var expr = N.egatable<MyClass>(x => x.Prop != 1);
somelist = someList.Where(!expr);
The N.egatable was just a small convenience syntax helper and largely unnecessary (EDIT: I wanted to avoid having to explicitly define MyClass or somehow make the instantiation of the object wrapper hidden, but couldn't quite get there and thought maybe someone would have a better idea):
public static class N
{
public static Negator<T> egatable<T>(Func<T, bool> underlyingFunction)
{
return new Negator<T>(underlyingFunction);
}
}
Negator<T> is where the real "magic" happens:
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));
}
}
First the ! operator overload performs the function negation (just as in this answer), then the implicit conversion operator to Func<T, bool> lets it pass in to the Where extension method.
Perhaps very silly is you can keep flipping it back and forth like this:
somelist = someList.Where(!!expr);
somelist = someList.Where(!!!expr);
somelist = someList.Where(!!!!expr);
somelist = someList.Where(!!!!!expr);
somelist = someList.Where(!!!!!!expr); //oh my what
So again... please don't do this. :) Definitely stick to the proper/sane way of doing things as in Steven's answer.
EDIT: Here's an implementation using expressions which works the exact same way in terms of syntax usage. Not sure if it's "correct", and haven't tested it against 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);
}
}

Related

Custom Expression as parameter and returning IEnumerable of generic type

I am trying to create an extension method that "extends" on an IEnumerable of a type, accepts an expression as a parameter and returns an IEnumerable of the same type.
public static IEnumerable<T> CustomExtension<T>(this IEnumerable<T> cities, Expression<Func<T, bool>> predicate)
{
return Enumerable.Where(cities, predicate);
//the line above is wrong, doesn't compile, but it explains my intentions...
}
Then call it like so:
var bigCities = cities.CustomExtension(c => c.occupants >= 1000000);
OR
var coldCities = cities.CustomExtension(c => c.avgTemp <= 20);
NOTE: It isn't just for "city" objects, the plan is to keep it generic so I can use the same method on similar types
Thanks in advance...
public static IEnumerable<T> CustomExtension<T>(this IEnumerable<T> cities, Func<T, bool> predicate)
{
return cities.Where(x => predicate(x));
}

Reduce a LambdaExpression Signature

I couldn't think of a better way to word the question, but what I'm trying to do is reduce the signature of a LambdaExpression from Expression<Func<MyObject, FilterObject, bool>> to Expression<Func<MyObject, bool>> by handling the instance of the FilterObject before the LambdaExpression is evaluated.
Here's a quick example:
AddFilter("Filter Name", FilterTypes.All,
(x, y) => GetConjunctionResult(
x.PersonA.IsSomething, x.PersonB.IsSomething, y.ConjunctionType));
private static bool GetConjunctionResult(bool personA, bool personB,
ConjunctionType conjunctionType)
{
switch (conjunctionType)
{
case ConjunctionType.Both:
return personA && personB:
case ConjunctionType.Either:
return personA && personB;
case ConjunctionType.PersonA:
return personA;
case ConjunctionType.PersonB:
return personB;
case ConjunctionType.Neither:
return !personA && !personB;
}
}
So I want this overload of AddFilter to create an object of type FilterObject and embed it into a LambdaExpression along the lines of:
var filter = new FilterObject();
// create Expression<Func<MyObject, bool>> lambda = x => GetConjunctionResult(
// x.PersonA.IsSomething, x.PersonB.IsSomething, filter.ConjunctionType));
Now there might be a better way to do this, so I'm open to any suggestions that eschew this approach altogether.
Given
var filter = new FilterObject()
it should be:
Expression<Func<MyObject, bool>> exp2 =
Expression.Lambda<Func<MyObject, bool>>(
Expression.Invoke(myExp,
myExp.Parameters[0],
Expression.Constant(filter)),
myExp.Parameters[0]);
Expression.Invoke will call the other expression and pass as the first parameter the first parameter of the new expression, and as the second parameter an Expression.Constant with your filter.
Are you trying to use Currying with Expression trees?
A better approach than calling Invoke is to substitute the parameter in the Expression tree directly using a ExpressionVisitor. You can define a couple of simple extension methods to make this easy. In this case they can apply the first parameter of the expression (you'd need to change your signature or adapt them to apply a middle parameter).
Usage:
var applied = expr.Apply(constValueForFirstParameter);
In a static class define these extension methods:
public static Expression<Func<U, V, bool>> Apply<T, U, V>(this Expression<Func<T, U, V, bool>> input, T value)
{
var swap = new ExpressionSubstitute(input.Parameters[0], Expression.Constant(value));
var lambda = Expression.Lambda<Func<U, V, bool>>(swap.Visit(input.Body), input.Parameters[1], input.Parameters[2]);
return lambda;
}
public static Expression<Func<U, bool>> Apply<T, U>(this Expression<Func<T, U, bool>> input, T value)
{
var swap = new ExpressionSubstitute(input.Parameters[0], Expression.Constant(value));
var lambda = Expression.Lambda<Func<U, bool>>(swap.Visit(input.Body), input.Parameters[1]);
return lambda;
}
class ExpressionSubstitute : System.Linq.Expressions.ExpressionVisitor
{
private readonly Expression from, to;
public ExpressionSubstitute(Expression from, Expression to)
{
this.from = from;
this.to = to;
}
public override Expression Visit(Expression node)
{
if (node == from) return to;
return base.Visit(node);
}
}

Convert Predicate<T> to Expression<Func<T, bool>>

Is possible to convert a Predicate<T> to Expression<Func<T, bool>> in some way?
I would like to use the next IQueryable function using the filters of the my ICollectionView:
public static System.Linq.IQueryable<TSource> Where<TSource>(this System.Linq.IQueryable<TSource> source, System.Linq.Expressions.Expression<System.Func<TSource, bool>> predicate)
Thanks
Something like this?
Predicate<string> predicate = input => input.Length > 0;
Expression<Func<string, bool>> expression = (input) => predicate(input);
You can probably make an extension Where method for your ICollectionView which takes a predicate, converts it to an Expression like this, and then call the Where method provided by Linq.
public static IQueryable<T> Where(this IQueryable<T> source, Predicate<T> predicate)
{
return source.Where(x => predicate(x));
}
In theory it is possible to convert a delegate 'back' to an expression, because you can request the emitted IL of a delegate, which gives you the information you need to transform it back.
However, it's for a reason that neither LINQ to SQL and Entity Framework do this. It is complex, fragile, and performance intensive to do so.
So the short answer is, you can't transform it to an expression.
namespace ConsoleApplication1
{
static class Extensions
{
public static Expression<Func<T, bool>> ToExpression<T>(this Predicate<T> p)
{
ParameterExpression p0 = Expression.Parameter(typeof(T));
return Expression.Lambda<Func<T, bool>>(Expression.Call(p.Method, p0),
new ParameterExpression[] { p0 });
}
}
}

LINQ-to-SQL : Convert Func<T, T, bool> to an Expression<Func<T, T, bool>>

LINQ-to-SQL has been a PITA for me. We're using it to communicate to the database, and then send entities via WCF to a Silverlight app. Everything was working fine, until it came time to start editing (CUD) the entities, and their related data.
I was finally able to devise two for loops that allowed the CUD. I tried to refactor them, and I was so close, until I learned that I can't always do Lambda with L2S.
public static void CudOperation<T>(this DataContext ctx, IEnumerable<T> oldCollection, IEnumerable<T> newCollection, Func<T, T, bool> predicate)
where T : class
{
foreach (var old in oldCollection)
{
if (!newCollection.Any(o => predicate(old, o)))
{
ctx.GetTable<T>().DeleteAllOnSubmit(ctx.GetTable<T>().Where(o => predicate(old, o)));
}
}
foreach (var newItem in newCollection)
{
var existingItem = oldCollection.SingleOrDefault(o => predicate(o, newItem));
if (existingItem != null)
{
ctx.GetTable<T>().Attach(newItem, existingItem);
}
else
{
ctx.GetTable<T>().InsertOnSubmit(newItem);
}
}
}
Called by:
ctx.CudOperation<MyEntity>(myVar.MyEntities, newHeader.MyEntities,
(x, y) => x.PkID == y.PkID && x.Fk1ID == y.Fk1ID && x.Fk2ID == y.FK2ID);
This almost worked. However, my Func needs to be an Expression>, and that's where I'm stuck.
Is there anyone who can tell me if this is possible? We have to be in .NET 3.5 due to SharePoint 2010.
Just change the parameter from:
Func<T, T, bool> predicate
To:
Expression<Func<T, T, bool>> predicate
The Expression is generated by the compiler.
Now, the issue is how to use this.
In your case, you need both a Func and an Expression, since you're using it in Enumerable LINQ queries (func based) as well as the SQL LINQ queries (expression based).
In:
.Where(o => predicate(old, o))
The old parameter is fixed. So we could change the parameter to:
Func<T, Expression<Func<T, bool>>> predicate
This means we can supply one argument (the 'fixed' one) and get back an expression.
foreach (var old in oldCollection)
{
var condition = predicate(old);
// ...
{
ctx.GetTable<T>().DeleteAllOnSubmit(ctx.GetTable<T>().Where(condition));
}
}
We also need to use this in Any. To get a Func from an Expression we can call Compile():
foreach (var old in oldCollection)
{
var condition = predicate(old);
if (!newCollection.Any(condition.Compile()))
{
ctx.GetTable<T>().DeleteAllOnSubmit(ctx.GetTable<T>().Where(condition));
}
}
You can do the same thing with the next part.
There are two issues:
The performance might be impacted by using Compile() lots. I'm not sure how much effect it would actually have, but I'd profile it to check.
The usage is now a little weird, since this is a curried lambda. Instead of passing (x,y) => ... you will be passing x => y => .... I'm not sure if this is a big deal for you.
There might be a better way to do this :)
Here's an alternate method, which should be a bit faster, since the Expression only has to be compiled once. Create a rewriter that will 'apply' one argument, like this:
class PartialApplier : ExpressionVisitor
{
private readonly ConstantExpression value;
private readonly ParameterExpression replace;
private PartialApplier(ParameterExpression replace, object value)
{
this.replace = replace;
this.value = Expression.Constant(value, value.GetType());
}
public override Expression Visit(Expression node)
{
var parameter = node as ParameterExpression;
if (parameter != null && parameter.Equals(replace))
{
return value;
}
else return base.Visit(node);
}
public static Expression<Func<T2,TResult>> PartialApply<T,T2,TResult>(Expression<Func<T,T2,TResult>> expression, T value)
{
var result = new PartialApplier(expression.Parameters.First(), value).Visit(expression.Body);
return (Expression<Func<T2,TResult>>)Expression.Lambda(result, expression.Parameters.Skip(1));
}
}
Then use it like this:
public static void CudOperation<T>(this DataContext ctx,
IEnumerable<T> oldCollection,
IEnumerable<T> newCollection,
Expression<Func<T, T, bool>> predicate)
where T : class
{
var compiled = predicate.Compile();
foreach (var old in oldCollection)
{
if (!newCollection.Any(o => compiled(o, old)))
{
var applied = PartialApplier.PartialApply(predicate, old);
ctx.GetTable<T>().DeleteAllOnSubmit(ctx.GetTable<T>().Where(applied));
}
}
foreach (var newItem in newCollection)
{
var existingItem = oldCollection.SingleOrDefault(o => compiled(o, newItem));
if (existingItem != null)
{
ctx.GetTable<T>().Attach(newItem, existingItem);
}
else
{
ctx.GetTable<T>().InsertOnSubmit(newItem);
}
}
}

method with a return type of "Expression"

Is it possible to create a method which returns a lambda expression? I couldn't find any proper examples.
The following syntax doesn't work, of course. It's just to visualize my idea a bit:
// Executed code
var filteredList = listWithNames.Where(GetLambdaExpression("Adam"));
// method
public Expression GetLambdaExpression(string name)
{
return listElement => listElement.Name == name;
}
You can create functions which return expressions such as this as a simple example in a predicate builder:
public static Expression<Func<T, bool>> True<T>() { return param => true; }
or this expression builder:
static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second, Func<Expression, Expression, Expression> merge)
{
var map = first.Parameters
.Select((f, i) => new { f, s = second.Parameters[i] })
.ToDictionary(p => p.s, p => p.f);
var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);
return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
}
in your example case You should use what Leppie has mentioned below (which I have upvoted)
<Func<TypeOflistElement,bool>>
public Expression<Func<TypeOflistElement,bool>> GetLambdaExpression(string name)
{
return listElement => listElement.Name == name;
}
You can return Func<bool, T> type like this
// Executed code
var filteredList = listWithNames.Where(GetLambdaExpression("Adam"));
// method
public Func<bool, ListElementTypeName> GetLambdaExpression(string name)
{
return listElement => listElement.Name == name;
}
But I can't understand what exactly you are trying to do with it.
You have to return Func<> since IEnumerable expects one, as in your example it would be:
public Func<String,Bool> (string name){..}
Where method for IEnumerable<T> expects delegate for Func<T, bool> method, so GetLambdaExpression() must return Func<T, bool>
Where method for IQueryable<T> expects Expression<Func<T, bool>>, so GetLambdaExpression() must return Expression<Func<T, bool>>.
Expression can be converted to delegate by invoking Compile() method.

Categories