title: Getting the values of the collection from Expression with Lambda - .Contains
body: <h2>Getting the values of the collection from Expression with Lambda - .Contains</h2>
  
  <p>I'm trying to get all values from the collection that contains a member in IQueryable. However, it seems that different collections behave differently.</p>
  
  <p>Consider the following listing:</p>
  
  <pre><code> var sampleData = new List&lt;MyClass&gt; { new MyClass { MyMember = "a" }, new MyClass { MyMember = "b" }, new MyClass { MyMember = "c" } };
   IEnumerable&lt;string&gt; samplEnumerable = new List&lt;string&gt; { "b", "a" };
   List&lt;string&gt; sampleList = new List&lt;string&gt; { "b", "a" };
   var resultTest1 = sampleData.AsQueryable().GetCalledMemberAndValidValues(x =&gt; (new[] { "b", "a" }).Contains(x.MyMember));
   var resultTest2 = sampleData.AsQueryable().GetCalledMemberAndValidValues(x =&gt; sampleList.Contains(x.MyMember));
   var resultTest3 = sampleData.AsQueryable().GetCalledMemberAndValidValues(x =&gt; samplEnumerable.Contains(x.MyMember));
  </code></pre>
  
  <p><code>Extension Method</code></p>
  
  <pre><code>public static class ExtensionMethods
  {
     public static dynamic GetCalledMemberAndValidValues&lt;T&gt;(this IQueryable&lt;T&gt; query, Expression&lt;Func&lt;T, bool&gt;&gt; predicate)
      {
        string parameterName = string.Empty;
        ArrayList values = new ArrayList();
    MethodCallExpression node = (MethodCallExpression)predicate.Body;
  
    if (predicate.Body.NodeType == ExpressionType.Call)
    {
      if ((node.Method.Name == "Contains"))
      {
        Type valueType = null;
        foreach (var obj in node.Arguments)
        {
          if (obj.NodeType == ExpressionType.MemberAccess &amp;&amp; ((MemberExpression)obj).Expression.NodeType == ExpressionType.Parameter)
          {
            parameterName = ((MemberExpression)obj).Member.Name;
          }
  
          // The below block is valid for array[];
          if (obj.NodeType == ExpressionType.NewArrayInit)
          {
            values.AddRange(((NewArrayExpression)obj).Expressions);
          }
  
          // The below block is valid for IEnumerable&lt;T&gt;;
          if (obj.NodeType == ExpressionType.MemberAccess &amp;&amp; ((MemberExpression)obj).Expression.NodeType == ExpressionType.Constant)
          {
            var value = (((MemberExpression) obj).Member as FieldInfo).GetValue(((obj as MemberExpression).Expression as ConstantExpression).Value);
  
            values.AddRange((ICollection)value);
          }
        }
  
        // The below block is valid for List&lt;T&gt;;
        if ((predicate.Body as MethodCallExpression).Object != null)
        {
          var obj = (MemberExpression)(predicate.Body as MethodCallExpression).Object;
          var value = (obj.Member as FieldInfo).GetValue((obj.Expression as ConstantExpression).Value);
          values.AddRange((ICollection)value);
        }
      }
    }
  
    return new { parameterName, values };
  }
  }
  </code></pre>
  
  <p><code>MethodCallExpression</code> object stores the property name <code>MyMember</code> in the field <code>Arguments</code> and the value gets stored in the field <code>Object</code>.</p>
  
  <p><code>MethodCallExpression</code> object stores both the property name <code>MyMember</code>and its value in the field <code>Arguments</code>.</p>
  
  <p>As you can see, all three examples produce the same result.</p>
  
  <p>However, i am not happy with having to deal with each collection type differently.</p>
  
  <p>How to generalise this and get the property name and value from the same field of the <code>MethodCallExpression</code>?</p>