【问题标题】:Nested Linq query (multiple levels)嵌套 Linq 查询(多级)
【发布时间】:2017-05-16 09:08:07
【问题描述】:

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

上下文: 对于每个类,使用类名获取相应的方法。使用类名/方法名的每种组合,我都可以调用元数据来获取源代码(字符串)。然后我编译那个字符串和那个Results in 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());
                    }
                }
            }
        }

【问题讨论】:

    标签: c# linq nested


    【解决方案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())
    
                   ));
    

    SelectSelectMany 是一对一的对应关系,这将对应于 Haskell 中的 bind

    注意在Linq中获取函数组合很简单,如上图。

    【讨论】:

    • 谢谢!我已经接近了,但没有信号。你的解决方案做到了!
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-21
      • 1970-01-01
      • 2021-06-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多