title: Unable to create a compound Expression<Func<string, bool>> from a set of expressions
body: <p>(Answer towards the bottom)</p>
  
  <p>I'm trying to build a system that combines </p>
  
  <pre><code>Func&lt;T, bool&gt; 
  </code></pre>
  
  <p>delegates into an ExpressionTree that allows me to pass in a value (badValue in this case) and get a bool out if the predicates all return true and the binary operations are taken into account.  This is my first time using Expression/ExpressionTrees, so please be gentle.</p>
  
  <p>I'm getting this error:</p>
  
  <blockquote>
    <p>ArgumentException: Expression of type 'System.Boolean' cannot be invoked</p>
  </blockquote>
  
  <p>on this line:</p>
  
  <pre><code>collectAnswers = Expression.And(isEmpty.Body, Expression.Invoke(...
  </code></pre>
  
  <p>I've got that line set up that way because I need to share the reference to <code>value</code> among all the Expressions (right?).</p>
  
  <p>My ideal scenario is to just have a bunch of </p>
  
  <pre><code>Expression&lt;Func&lt;blah, blah, bool&gt;&gt; 
  </code></pre>
  
  <p>and I can pass these into a system alongside logical operators (And/Or/Not) and get a bool out at the end.  Hoping to allow a dynamic building of rules that a value has to pass through.</p>
  
  <p>Is that even possible in the route I'm going?  If not, a couple of pointers directing me down the right path would be appreciated.</p>
  
  <pre><code>string badValue = "hello!";
  const int minSize = 8;
  const int maxSize = 30;
  
  Expression&lt;Func&lt;string, bool&gt;&gt; stringLengthMax = value =&gt; value.Length &lt; maxSize;
  Expression&lt;Func&lt;string, bool&gt;&gt; stringLengthMin = value =&gt; value.Length &gt; minSize;
  Expression&lt;Func&lt;string, bool&gt;&gt; isEmpty = value =&gt; !string.IsNullOrEmpty(value);
  
  BinaryExpression collectAnswers = Expression.And(stringLengthMax.Body, Expression.Invoke(stringLengthMin, stringLengthMax.Parameters));
  collectAnswers = Expression.And(isEmpty.Body, Expression.Invoke(collectAnswers, stringLengthMax.Parameters));
  
  Func&lt;string, bool&gt; shouldValidate = Expression.Lambda&lt;Func&lt;string, bool&gt;&gt;(collectAnswers, stringLengthMax.Parameters).Compile();
  bool result = shouldValidate(badValue);
  </code></pre>
  
  <p><strong>Answer</strong>
  I wasn't pushing through the parameter(s) the right way, below is an example of multiple parameters shared among several Expressions that are put into an ExpressionTree and a single boolean comes out of the compiled Func, isValid</p>
  
  <pre><code>const int minSize = 8;
  const int maxSize = 30;
  
  Expression&lt;Func&lt;string, int, bool&gt;&gt; stringLengthMax = (value, max) =&gt; value.Length &lt;= max;
  Expression&lt;Func&lt;string, int, bool&gt;&gt; stringLengthMin = (value, min) =&gt; value.Length &gt;= min;
  Expression&lt;Func&lt;string, bool&gt;&gt; isEmpty = value =&gt; string.IsNullOrEmpty(value);
  
  ParameterExpression valueParameter = Expression.Parameter(typeof(string));
  ParameterExpression minParameter = Expression.Parameter(typeof(int));
  ParameterExpression maxParameter = Expression.Parameter(typeof(int));
  
  Expression&lt;Func&lt;string, int, int, bool&gt;&gt; minMaxCheck =
      Expression.Lambda&lt;Func&lt;string, int, int, bool&gt;&gt;(
          Expression.And(Expression.Invoke(stringLengthMax, valueParameter, maxParameter), 
              Expression.Invoke(stringLengthMin, valueParameter, minParameter)), valueParameter, minParameter, maxParameter);
  
  minMaxCheck = Expression.Lambda&lt;Func&lt;string, int, int, bool&gt;&gt;(
      Expression.And(Expression.Invoke(minMaxCheck, valueParameter, minParameter, maxParameter), 
          Expression.Not(Expression.Invoke(isEmpty, valueParameter))), valueParameter, minParameter, maxParameter);
  
  Func&lt;string, int, int, bool&gt; isValid = minMaxCheck.Compile();
  bool resultFalse1 = isValid("hello!", minSize, maxSize); // false - too short
  bool resultTrue1 = isValid("hello!", "hello!".Length, maxSize); // true - adjust min
  bool resultFalse2 = isValid("1234567890123456789012345678901", minSize, maxSize); // false - too long
  bool resultTrue2 = isValid("1234567890123456789012345678901", minSize, "1234567890123456789012345678901".Length); // true - adjust max
  bool resultFalse3 = isValid(string.Empty, minSize, maxSize); // false - empty
  bool shouldBeTrue = isValid("1234567890", minSize, maxSize); // true - just right
  bool resultFalse4 = isValid("1234567890", maxSize, maxSize); // false - adjust min
  bool resultFalse5 = isValid("1234567890", minSize, minSize); // false - adjust max
  </code></pre>