title: Do not nest generic types in member signatures
body: <p>I have acquired an extension class which implements the following members with signatures that are violating the CA1006:DoNotNestGenericTypesInMemberSignatures rule.</p>
  
  <p>The code to which the warning refers is included below.</p>
  
  <p>How should I refactor the code to resolve the CA1006 warning?  </p>
  
  <p>Please keep in mind that I am not very familiar with expression trees, although I do have a pretty good grasp of anonymous methods, delegates, and lambdas.</p>
  
  <p>Any help will be greatly appreciated.</p>
  
  <pre><code>    public static DataServiceQuery&lt;TElement&gt; Expand&lt;TElement, TPropType&gt;(this DataServiceQuery&lt;TElement&gt; source, Expression&lt;Func&lt;TElement, TPropType&gt;&gt; propertySelector) 
      {
          string includeString = BuildString(propertySelector);
          return source.Expand(includeString);
      }
  
      private static string BuildString(Expression propertySelector)
      {
          switch (propertySelector.NodeType)
          {
              case ExpressionType.Lambda:
                  LambdaExpression lambdaExpression = (LambdaExpression)propertySelector;
                  return BuildString(lambdaExpression.Body);
  
              case ExpressionType.Quote:
                  UnaryExpression unaryExpression = (UnaryExpression)propertySelector;
                  return BuildString(unaryExpression.Operand);
  
              case ExpressionType.MemberAccess:
  
                  MemberExpression memberExpression = (MemberExpression)propertySelector;
                  MemberInfo propertyInfo = memberExpression.Member;
  
                  if (memberExpression.Expression is ParameterExpression)
                  {
                      return propertyInfo.Name;
                  }
                  else
                  {
                      // we've got a nested property (e.g. MyType.SomeProperty.SomeNestedProperty)
                      return BuildString(memberExpression.Expression) + "/" + propertyInfo.Name;
                  }
  
              case ExpressionType.Call:
                  MethodCallExpression methodCallExpression = (MethodCallExpression)propertySelector;
                  if (IsSubInclude(methodCallExpression.Method)) // check that it's a SubInclude call
                  {
                      // argument 0 is the expression to which the SubInclude is applied (this could be member access or another SubInclude)
                      // argument 1 is the expression to apply to get the included property
                      // Pass both to BuildString to get the full expression
                      return BuildString(methodCallExpression.Arguments[0]) + "/" +
                             BuildString(methodCallExpression.Arguments[1]);
                  }
                  // else drop out and throw
                  break;
          }
          throw new InvalidOperationException("Expression must be a member expression or an SubInclude call: " + propertySelector.ToString());
  
      }
  
      private static readonly MethodInfo[] SubIncludeMethods;
      static MyExtensions()
      {
          Type type = typeof(MyExtensions);
          SubIncludeMethods = type.GetMethods().Where(mi =&gt; mi.Name == "SubExpand").ToArray();
      }
  
      private static bool IsSubInclude(MethodInfo methodInfo)
      {
          if (methodInfo.IsGenericMethod)
          {
              if (!methodInfo.IsGenericMethodDefinition)
              {
                  methodInfo = methodInfo.GetGenericMethodDefinition();
              }
          }
          return SubIncludeMethods.Contains(methodInfo);
      }
  
      public static TPropType SubExpand&lt;TSource, TPropType&gt;(this Collection&lt;TSource&gt; source, Expression&lt;Func&lt;TSource, TPropType&gt;&gt; propertySelector)
          where TSource : class
          where TPropType : class
      {
          throw new InvalidOperationException("This method is only intended for use with DataServiceQueryExtensions.Expand to generate expressions trees"); // no actually using this - just want the expression! 
      }
  
      public static TPropType SubExpand&lt;TSource, TPropType&gt;(this TSource source, Expression&lt;Func&lt;TSource, TPropType&gt;&gt; propertySelector)
          where TSource : class
          where TPropType : class
      {
          throw new InvalidOperationException("This method is only intended for use with DataServiceQueryExtensions.Expand to generate expressions trees"); // no actually using this - just want the expression! 
      }
  </code></pre>