CA1006 : DoNotNestGenericTypesInMemberSignatures 규칙을 위반하는 다음 멤버를 구현하는 확장 클래스를 얻었습니다.구성원 서명에 제네릭 형식을 중첩시키지 마십시오.
경고가 참조하는 코드는 다음과 같습니다.
CA1006 경고를 해결하기 위해 코드를 어떻게 리팩터링해야합니까?
익명 메서드, 대리자 및 람다에 대해 잘 알고 있지만 식 트리에 익숙하지 않습니다.
도움이 될 것입니다.
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
public 메소드의 propertySelector 매개 변수를 언급하고 있습니까? 이 경고는 메서드에 대한 인터페이스를 사용할 수 있도록하는 것에 관한 것입니다. 그러나 Expression에서는 속성 또는 메서드 호출에서 반환 값으로 제공하는 클래스에서 expression 매개 변수를 래핑하지 않는 한 리팩토링되지 않습니다. – Jay
DiskJunky,이 문제를 해결하는 데 관심을 가져 주셔서 감사합니다. 본질적으로 코드는 다음과 같이 람다 식을 작성하는 데 사용됩니다. var scenarioGroups = ctx.ScenarioGroups.Expand의 scenarioGroup (scenarioGroup => scenarioGroup.Scenarios.SubExpand (sc => sc.XYLines.SubExpand (xy => xy.Points))) 여기서 ... –