Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 不要在成员签名中嵌套泛型类型_C#_Linq_Expression Trees - Fatal编程技术网

C# 不要在成员签名中嵌套泛型类型

C# 不要在成员签名中嵌套泛型类型,c#,linq,expression-trees,C#,Linq,Expression Trees,我获得了一个扩展类,它实现了以下成员,这些成员的签名违反了CA1006:DoNotNestGenericTypesInMemberSignatures规则 下面包括警告所指的代码 我应该如何重构代码以解决CA1006警告 请记住,我对表达式树不是很熟悉,尽管我对匿名方法、委托和lambda有很好的掌握 任何帮助都将不胜感激 public static DataServiceQuery<TElement> Expand<TElement, TPropType>(th

我获得了一个扩展类,它实现了以下成员,这些成员的签名违反了CA1006:DoNotNestGenericTypesInMemberSignatures规则

下面包括警告所指的代码

我应该如何重构代码以解决CA1006警告

请记住,我对表达式树不是很熟悉,尽管我对匿名方法、委托和lambda有很好的掌握

任何帮助都将不胜感激

    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! 
    }
公共静态DataServiceQuery扩展(此DataServiceQuery源、表达式属性选择器)
{
字符串includeString=BuildString(propertySelector);
返回源.展开(includeString);
}
私有静态字符串BuildString(表达式属性选择器)
{
开关(propertySelector.NodeType)
{
大小写表达式类型。Lambda:
LambdaExpression LambdaExpression=(LambdaExpression)属性选择器;
返回BuildString(lambdaExpression.Body);
大小写表达式类型。引号:
UnaryExpression UnaryExpression=(UnaryExpression)属性选择器;
返回BuildString(unaryExpression.Operator);
case ExpressionType.MemberAccess:
MemberExpression MemberExpression=(MemberExpression)属性选择器;
MemberInfo propertyInfo=memberExpression.Member;
if(memberExpression.Expression是ParameterExpression)
{
返回propertyInfo.Name;
}
其他的
{
//我们有一个嵌套属性(例如MyType.SomeProperty.SomeNestedProperty)
返回BuildString(memberExpression.Expression)+“/”+propertyInfo.Name;
}
大小写表达式类型。调用:
MethodCallExpression MethodCallExpression=(MethodCallExpression)属性选择器;
if(IsSubInclude(methodCallExpression.Method))//检查它是否是子包含调用
{
//参数0是应用子包含的表达式(可以是成员访问或其他子包含)
//参数1是用于获取included属性的表达式
//将两者传递给BuildString以获取完整表达式
返回BuildString(methodCallExpression.Arguments[0])+“/”+
BuildString(methodCallExpression.Arguments[1]);
}
//否则就退学扔掉
打破
}
抛出新的InvalidOperationException(“表达式必须是成员表达式或子包含调用:“+propertySelector.ToString()”);
}
私有静态只读MethodInfo[]子IncludeMethods;
静态MyExtensions()
{
类型类型=类型(MyExtensions);
SubIncludeMethods=type.GetMethods()。其中(mi=>mi.Name==“SubExpand”).ToArray();
}
私有静态bool IsSubInclude(MethodInfo MethodInfo)
{
if(methodInfo.IsGenericMethod)
{
如果(!methodInfo.IsGenericMethodDefinition)
{
methodInfo=methodInfo.GetGenericMethodDefinition();
}
}
返回SubIncludeMethods.Contains(methodInfo);
}
公共静态TPropType子扩展(此集合源、表达式属性选择器)
where TSource:class
其中TPropType:class
{
抛出新的InvalidOperationException(“此方法仅用于DataServiceQueryExtensions.Expand以生成表达式树”);//不实际使用此方法-只需要表达式!
}
公共静态TPropType子扩展(此TSource源、表达式属性选择器)
where TSource:class
其中TPropType:class
{
抛出新的InvalidOperationException(“此方法仅用于DataServiceQueryExtensions.Expand以生成表达式树”);//不实际使用此方法-只需要表达式!
}

该警告是一个通用警告,旨在帮助您设计更好、更简单的公共界面。在这种情况下,您会收到一条关于方法中有
表达式
参数的警告。但是,对于此方法,简化类型没有意义,相反,您应该使用一个命令来抑制警告,或者从规则集中完全删除该规则


<> P>一个愚蠢的例子,你可能应该考虑遵循规则的建议是这样的一种方法:

public void F(Dictionary<String, List<Tuple<String, Int32>>> dictionary);
publicsvoidf(字典);

您能举一个使用此代码的示例吗?这是相当复杂和有点棘手,看看哪里的错误是指公共方法的propertySelector参数?警告是关于使方法的接口可用-但是对于表达式,我不知道如何重构它,除非您将表达式参数包装在一个类中,该类将其作为属性或方法调用的返回。DiskJunky,感谢您对帮助解决此问题的兴趣。本质上,代码用于构建lambda表达式,如下所示。var scenarioGroups=来自ctx.scenarioGroups.Expand中的scenarioGroup(scenarioGroup=>scenarioGroup.Scenarios.SubExpand(sc=>sc.XYLines.SubExpand(xy=>xy.Points)),其中…是的,Jay,是的。此外,我认为你的评估是正确的。然而,我被要求探索筑巢的可能替代方案,而不是抑制警告。感谢马丁的帮助。我相信你是对的。很明显,试图简化类型是毫无意义的。我只能抑制它。在保持这个警告一段时间后,我抑制了它,因为它会引起太多的噪音。发现99%的时间使用带有“深度”的嵌套泛型类型