我已经获得了一个扩展类,它实现了具有违反CA1006的签名的以下成员:DoNotNestGenericTypesInMemberSignatures规则。不要在成员签名中嵌套泛型类型
下面包含警告提到的代码。
我应该如何重构代码来解决CA1006警告?
请记住,我并不是很熟悉表达式树,尽管我对匿名方法,委托和lambdas有很好的理解。
任何帮助将不胜感激。
public static DataServiceQuery<TElement> Expand<TElement, TPropType>(this DataServiceQuery<TElement> source, Expression<Func<TElement, TPropType>> 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 => 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<TSource, TPropType>(this Collection<TSource> source, Expression<Func<TSource, TPropType>> 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<TSource, TPropType>(this TSource source, Expression<Func<TSource, TPropType>> 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!
}
你可以给这个代码的例子被使用?看到错误的位置很复杂,有点棘手 – DiskJunky 2013-02-18 21:03:54
是指公共方法的propertySelector参数吗?警告是关于使一个方法的接口可用 - 但是对于表达式,我没有看到它是如何被重构的,除非您将表达式参数包装在一个类中,该类将其作为属性或方法调用的返回提供。 – Jay 2013-02-18 21:07:45
DiskJunky,感谢您对帮助解决此问题感兴趣。基本上,这些代码正在用来构建如下所示的lambda表达式。 var scenarioGroups = from scenarioGroup in ctx.ScenarioGroups.Expand(scenarioGroup => scenarioGroup.Scenarios.SubExpand(sc => sc.XYLines.SubExpand(xy => xy.Points)))其中... – 2013-02-19 14:05:56