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:
Which method would you expect to be called in the following statement?