Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to negate a delegate?

This is my code, heavily abbreviated for simplicity

Func<Product, bool> selector;
...
selector = p => p.IsNew;
...
if(negative) // not selector
  selector = x => !selector(x); // This is wrong (causes infinite loop)
  // How do you do negate it? The result should be p => !p.IsNew

...
IEnumerable<Product> products = MyContext.Products.Where(selector);
like image 772
Aximili Avatar asked Mar 23 '23 21:03

Aximili


1 Answers

You can do this with a helper method:

public static Predicate<T> Negate<T>(this Predicate<T> predicate) {
    return t => !predicate(t);
}

(or, replace Predicate with Func<T, bool>).

Then:

selector = selector.Negate();

Your stack overflow issue is pretty obvious; you're defining selector in terms of itself1. The helper method avoids that problem.

1: That is, this will clearly cause a stack overflow too:

public bool M() { return !M(); }

Believe it or not, you're doing exactly the same thing.

like image 156
jason Avatar answered Apr 06 '23 00:04

jason