C# 嵌套Linq查询(多级)

C# 嵌套Linq查询(多级),c#,linq,nested,C#,Linq,Nested,如何将以下循环放入一个Linq查询中?我试图实现的最终结果是得到这些类方法中的语句列表 背景: 对于每个类,都使用类名获取相应的方法。对于类名/方法名的每个组合,我都可以调用元数据来获取源代码字符串。然后我编译这个字符串,结果得到一个Method对象,该对象具有和IEnumerable,其中包含该方法的所有代码语句。所以我要得到所有类和方法的语句列表 IXppcMetadataProvider serviceMetadataProvider = Program.getXppcMe

如何将以下循环放入一个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());
                    }
                }
            }
        }

基本上,您需要使用以下类似于高阶函数的Linq方法

当您有1对1的对应关系时选择,与SelectMany相反,它将对应于Haskell中的bind


请注意,在Linq中获取函数组合非常简单,如上所示。

转换为查询语法更容易,但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));

谢谢我很接近,但没有信号。。你的解决方案成功了!
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));