嵌套的Linq查询(多个级别)

时间:2017-05-16 09:08:08

标签: c# linq nested

如何将以下循环放入一个Linq查询中?我想要实现的最终结果是获取这些类方法中的语句列表。

上下文: 对于每个类,使用类名提取相应的方法。通过类名/方法名的每个组合,我可以调用元数据来获取源代码(字符串)。然后我编译该字符串,结果在Method对象中,IEnumerable包含该方法的所有代码语句。所以我要获得所有类和方法的语句列表。

        IXppcMetadataProvider serviceMetadataProvider = Program.getXppcMetadataProvider();

        IEnumerable<string> classNames = serviceMetadataProvider.ClassNames();

        MultipassAdministrator multipassAdmin = new MultipassAdministrator(serviceMetadataProvider);


        foreach (string className in classNames)
        {
            IEnumerable<string> classMethods = serviceMetadataProvider.ClassMethods(className);

            foreach (string methodName in classMethods)
            {
                string source = serviceMetadataProvider.GetClassMethodSource(className, methodName);

                Method method = multipassAdmin.CompileSingleMethod(source) as Method;

                if (method != null)
                {
                    foreach (Statement statement in method.Statements)
                    {
                        System.Console.WriteLine(statement.ToString());
                    }
                }
            }
        }

2 个答案:

答案 0 :(得分:1)

基本上你需要使用以下Linq方法,它们就像更高阶函数

System.Console.WriteLine(
    String.Join(Environment.NewLine,
                getXppcMetadataProvider().ClassNames().SelectMany(
                    className => getXppcMetadataProvider().ClassMethods(className)
                    .Select(
                        methodName => getXppcMetadataProvider()
                        .GetClassMethodSource(className, methodName)
                    ).Select(
                        source => new MultipassAdministrator(getXppcMetadataProvider())
                        .CompileSingleMethod(source) as mymeth)
                )
                .Where(method => method != null).SelectMany(
                    method => method.Statements
                ).Select(statement => statement.ToString())

               ));

Select当您与SelectMany相反时,对应于Haskell中的bind,则为1对1对应。

请注意,在Linq中直接获取功能组合,如上所示。

答案 1 :(得分:0)

转换为查询语法更容易,但LINQ更慢,更难以调试/理解。

var q = from nothing in new[] { 0 }
        let serviceMetadataProvider = Program.getXppcMetadataProvider()
        let classNames = serviceMetadataProvider.ClassNames()
        let multipassAdmin = new MultipassAdministrator(serviceMetadataProvider)

        from className in classNames
        let classMethods = serviceMetadataProvider.ClassMethods(className)

        from methodName in classMethods
        let source = serviceMetadataProvider.GetClassMethodSource(className, methodName)
        let method = multipassAdmin.CompileSingleMethod(source) as Method
        where method != null

        from statement in method.Statements
        select statement.ToString();

System.Console.WriteLine(String.Join(Environment.NewLine, q));