I am trying to create a PredicateBuilder<T>
class which wraps an Expression<Func<T, bool>>
and provides some methods to easily build up an expression with various And
and Or
methods. I thought it would be cool if I could use this PredicateBuilder<T>
as an Expression<Func<T, bool>>
directly, and thought this could be done by having an implicit operator
method thing.
Stripped down version of the class looks like this:
class PredicateBuilder<T>
{
public Expression<Func<T, bool>> Predicate { get; protected set; }
public PredicateBuilder(bool initialPredicate)
{
Predicate = initialPredicate
? (Expression<Func<T, bool>>) (x => true)
: x => false;
}
public static implicit operator Expression<Func<T, bool>>(
PredicateBuilder<T> expressionBuilder)
{
return expressionBuilder.Predicate;
}
}
Then, just as a test, I have this extention method in a static class:
public static void PrintExpression<T>(this Expression<Func<T, bool>> expression)
{
Console.WriteLine(expression);
}
In my head, I should then be able to do these:
var p = new PredicateBuilder<int>(true);
p.PrintExpression();
PredicateExtensions.PrintExpression(p);
However none of them work. For the first one, the extension method is not found. And for the second, it says that
The type arguments for method 'ExtravagantExpressions.PredicateHelper.PrintExpression(System.Linq.Expressions.Expression>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
So I tried the following, which worked:
PredicateExtensions.PrintExpression<int>(p);
Also, this works, of course:
((Expression<Func<int, bool>>) p).PrintExpression();
But yeah... why don't the others work? Have I misunderstood something about how this implicit operator
thing works?
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With