I am trying to create a PredicateBuilder
class which wraps an Expression
and provides some methods to easily bu
As Anton says, if you put the extension methods directly on Expression<Func<...>>
it would probably work.
More explanation... nothing particularly clever, but the idea would be that you don't have a PredicateBuilder
class that you create instances of. Instead you just have purely static building blocks:
public static class Predicates
{
public static Expression<Func<T, bool>> True<T>()
{
return x => true;
}
public static Expression<Func<T, bool>> False<T>()
{
return x => false;
}
public static Expression<Func<T, bool>> And<T>(
this Expression<Func<T, bool>> left,
Expression<Func<T, bool>> right)
{
return ... // returns equivalent of (left && right)
}
}
Those two functions True
and False
play the role of your PredicateBuilder(bool)
constructor, and you'd presumably have similar ones for primitive comparisons and so on, and then operators like And
would let you plug two expressions together.
However, then you lose the ability to use operator symbols, which you could have used with your wrapper object, and instead you have to use method names. I've been playing around with the same kind of approaches, and the thing I always come back to is that I want to be able to define extension operators. The C# team apparently considered these for 3.0 (along with extension properties) but they were lower priority because they didn't play a part in the overall aims of Linq.
This is not specific to extension methods. C# won't implicitly cast an object to another type unless there is a clue about the target type. Assume the following:
class A {
public static implicit operator B(A obj) { ... }
public static implicit operator C(A obj) { ... }
}
class B {
public void Foo() { ... }
}
class C {
public void Foo() { ... }
}
Which method would you expect to be called in the following statement?
new A().Foo(); // B.Foo? C.Foo?
No, you haven't, but C# compiler's type deduction isn't powerful enough to understand your code, and in particular, it doesn't look at implicit operators. You'll have to stick with Expression<Func<T,bool>>
— why not have extension methods like Or
, And
directly on expressions?